/// <summary> /// Gets the URL for the specified service by using WS-Inspection. /// </summary> /// <param name="host">Address and optionally port of the host server.</param> /// <param name="serviceName">Service name to find URL for.</param> /// <param name="user">The user to be authenticated.</param> /// <param name="password">The password of the user.</param> /// <returns>A URL that references the specified service.</returns> static public Uri GetServiceUrl(string host, string serviceName, string user, string password) { Uri serviceUrl = null; HttpWebResponse response = null; CookieContainer cks = new CookieContainer(); // Build a credential from the user name and password. NetworkCredential myCred = new NetworkCredential(user, password); // Parse the host string to see if it is a complete uri. Uri tempUri; try { if (host.StartsWith(Uri.UriSchemeHttp) || host.StartsWith(Uri.UriSchemeHttps)) { tempUri = new Uri(host.TrimEnd(new char[] { '/' }) + WSInspectionDocument); } else { tempUri = new Uri(Uri.UriSchemeHttp + Uri.SchemeDelimiter + host.TrimEnd(new char[] { '/' }) + WSInspectionDocument); } } catch { tempUri = new Uri(Uri.UriSchemeHttp + Uri.SchemeDelimiter + host.TrimEnd(new char[] { '/' }) + WSInspectionDocument); } // Create the web request. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tempUri); bool retry = true; proxyRetry: request.Credentials = myCred; request.Timeout = 15 * 1000; request.CookieContainer = cks; request.Proxy = ProxyState.GetProxyState(request.RequestUri); try { // Get the response from the web server. response = request.GetResponse() as HttpWebResponse; // Mono has a bug where it doesn't set the cookies in the cookie jar. if (response != null) { cks.Add(response.Cookies); } //cks.Add(response.Cookies); } catch (WebException we) { IsTrustFailure(host, we); if ((we.Status == WebExceptionStatus.Timeout) || (we.Status == WebExceptionStatus.NameResolutionFailure)) { throw we; } else { response = we.Response as HttpWebResponse; if (response != null) { // Mono has a bug where it doesn't set the cookies in the cookie jar. cks.Add(response.Cookies); if (response.StatusCode == HttpStatusCode.Unauthorized && retry == true) { // This should be a free call we must be behind iChain. request = (HttpWebRequest)WebRequest.Create(response.ResponseUri); retry = false; goto proxyRetry; } } response = null; } } // Make sure that there was an answer. if (response != null) { try { // Get the stream associated with the response. Stream receiveStream = response.GetResponseStream(); // Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); try { XmlDocument document = new XmlDocument(); document.Load(readStream); //Create an XmlNamespaceManager for resolving namespaces. XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable); nsmgr.AddNamespace("wsil", document.DocumentElement.NamespaceURI); // Search for the named service element. XmlNode serviceNode = document.DocumentElement.SelectSingleNode(WSIL_ServiceTag + "[" + WSIL_NameTag + "='" + "Domain Service" + "']", nsmgr); if (serviceNode != null) { // Get the description node. XmlElement description = serviceNode[WSIL_DescriptionTag]; if (description != null) { // Get the uri location. string uriString = description.GetAttribute(WSIL_LocationAttrTag); if (uriString != null) { // Fix up the URI if it is relative. if (!uriString.ToLower().StartsWith(Uri.UriSchemeHttp)) { Uri respUri = response.ResponseUri; UriBuilder urb = new UriBuilder(respUri.Scheme, respUri.Host, respUri.Port, uriString.TrimStart(new char[] { '/' })); serviceUrl = urb.Uri; // Check to see if we need to use ssl. // Make the request and see if we get redirected 302; // Create the web request. request = (HttpWebRequest)WebRequest.Create(serviceUrl); request.CookieContainer = cks; request.Proxy = ProxyState.GetProxyState(request.RequestUri); response.Close(); try { response = request.GetResponse() as HttpWebResponse; serviceUrl = response.ResponseUri; } catch (WebException wex) { IsTrustFailure(host, wex); response = wex.Response as HttpWebResponse; if (response != null) { if (response.StatusCode == HttpStatusCode.Unauthorized) { if (response.Headers.Get("Simias-Error") != null) { // This is expected because this service requires authentication. serviceUrl = response.ResponseUri; } } } } } else { serviceUrl = new Uri(uriString); } } } } } finally { readStream.Close(); } } finally { if (response != null) { response.Close(); } } } return(serviceUrl); }