/// <summary>
/// Updates an endpoint with information from the server's discovery endpoint.
/// </summary>
public void UpdateFromServer(
Uri endpointUrl,
MessageSecurityMode securityMode,
string securityPolicyUri)
{
// get the a discovery url.
Uri discoveryUrl = GetDiscoveryUrl(endpointUrl);
// create the discovery client.
DiscoveryClient client = DiscoveryClient.Create(discoveryUrl, m_configuration);
try
{
// get the endpoints.
EndpointDescriptionCollection collection = client.GetEndpoints(null);
if (collection == null || collection.Count == 0)
{
throw ServiceResultException.Create(
StatusCodes.BadUnknownResponse,
"Server does not have any endpoints defined.");
}
// find list of matching endpoints.
EndpointDescriptionCollection matches = new EndpointDescriptionCollection();
// first pass - match on the requested security parameters.
foreach (EndpointDescription description in collection)
{
// check for match on security policy.
if (!String.IsNullOrEmpty(securityPolicyUri))
{
if (securityPolicyUri != description.SecurityPolicyUri)
{
continue;
}
}
// check for match on security mode.
if (securityMode != MessageSecurityMode.Invalid)
{
if (securityMode != description.SecurityMode)
{
continue;
}
}
// add to list of matches.
matches.Add(description);
}
// no matches (security parameters may have changed).
if (matches.Count == 0)
{
matches = collection;
}
// check if list has to be narrowed down further.
if (matches.Count > 1)
{
collection = matches;
matches = new EndpointDescriptionCollection();
// second pass - match on the url scheme.
foreach (EndpointDescription description in collection)
{
// parse the endpoint url.
Uri sessionUrl = Utils.ParseUri(description.EndpointUrl);
if (sessionUrl == null)
{
continue;
}
// check for matching protocol.
if (sessionUrl.Scheme != endpointUrl.Scheme)
{
continue;
}
matches.Add(description);
}
}
// no matches (protocol may not be supported).
if (matches.Count == 0)
{
matches = collection;
}
// choose first in list by default.
EndpointDescription match = matches[0];
// check if list has to be narrowed down further.
if (matches.Count > 1)
{
// third pass - match based on security level.
foreach (EndpointDescription description in matches)
{
if (description.SecurityMode > match.SecurityMode)
{
match = description;
}
}
}
// check if the endpoint url matches the endpoint used in the request.
Uri matchUrl = Utils.ParseUri(match.EndpointUrl);
if (matchUrl == null || String.Compare(discoveryUrl.DnsSafeHost, matchUrl.DnsSafeHost, StringComparison.OrdinalIgnoreCase) != 0)
{
UriBuilder uri = new UriBuilder(matchUrl);
uri.Host = discoveryUrl.DnsSafeHost;
uri.Port = discoveryUrl.Port;
match.EndpointUrl = uri.ToString();
// need to update the discovery urls.
match.Server.DiscoveryUrls.Clear();
match.Server.DiscoveryUrls.Add(discoveryUrl.ToString());
}
// update the endpoint.
Update(match);
}
finally
{
client.Close();
}
}