/// <summary> /// Initializes a new instance of the <see cref="DiscoveryResult"/> class. /// </summary> /// <param name="requestUri">The request URI.</param> /// <param name="initialResponse">The initial response.</param> /// <param name="finalResponse">The final response.</param> /// <returns>The newly initialized instance.</returns> internal static async Task <DiscoveryResult> CreateAsync(Uri requestUri, HttpResponseMessage initialResponse, HttpResponseMessage finalResponse) { var result = new DiscoveryResult(); result.RequestUri = requestUri; result.NormalizedUri = initialResponse.RequestMessage.RequestUri; if (finalResponse == null || finalResponse.StatusCode != HttpStatusCode.OK) { await result.ApplyHtmlResponseAsync(initialResponse); } else { result.ContentType = finalResponse.Content.Headers.ContentType; result.ResponseText = await finalResponse.Content.ReadAsStringAsync(); result.IsXrds = true; if (initialResponse != finalResponse) { result.YadisLocation = finalResponse.RequestMessage.RequestUri; } // Back up the initial HTML response in case the XRDS is not useful. result.htmlFallback = initialResponse; } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="DiscoveryResult"/> class. /// </summary> /// <param name="requestUri">The request URI.</param> /// <param name="initialResponse">The initial response.</param> /// <param name="finalResponse">The final response.</param> /// <returns>The newly initialized instance.</returns> internal static async Task<DiscoveryResult> CreateAsync(Uri requestUri, HttpResponseMessage initialResponse, HttpResponseMessage finalResponse) { var result = new DiscoveryResult(); result.RequestUri = requestUri; result.NormalizedUri = initialResponse.RequestMessage.RequestUri; if (finalResponse == null || finalResponse.StatusCode != HttpStatusCode.OK) { await result.ApplyHtmlResponseAsync(initialResponse); } else { result.ContentType = finalResponse.Content.Headers.ContentType; result.ResponseText = await finalResponse.Content.ReadAsStringAsync(); result.IsXrds = true; if (initialResponse != finalResponse) { result.YadisLocation = finalResponse.RequestMessage.RequestUri; } // Back up the initial HTML response in case the XRDS is not useful. result.htmlFallback = initialResponse; } return result; }
/// <summary> /// Performs YADIS discovery on some identifier. /// </summary> /// <param name="hostFactories">The host factories.</param> /// <param name="uri">The URI to perform discovery on.</param> /// <param name="requireSsl">Whether discovery should fail if any step of it is not encrypted.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The result of discovery on the given URL. /// Null may be returned if an error occurs, /// or if <paramref name="requireSsl" /> is true but part of discovery /// is not protected by SSL. /// </returns> public static async Task <DiscoveryResult> DiscoverAsync(IHostFactories hostFactories, UriIdentifier uri, bool requireSsl, CancellationToken cancellationToken) { Requires.NotNull(hostFactories, "hostFactories"); Requires.NotNull(uri, "uri"); HttpResponseMessage response; try { if (requireSsl && !string.Equals(uri.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { Logger.Yadis.WarnFormat("Discovery on insecure identifier '{0}' aborted.", uri); return(null); } response = await RequestAsync(uri, requireSsl, hostFactories, cancellationToken, ContentTypes.Html, ContentTypes.XHtml, ContentTypes.Xrds); if (response.StatusCode != System.Net.HttpStatusCode.OK) { Logger.Yadis.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response.StatusCode, response.StatusCode, uri); return(null); } await response.Content.LoadIntoBufferAsync(); } catch (ArgumentException ex) { // Unsafe URLs generate this Logger.Yadis.WarnFormat("Unsafe OpenId URL detected ({0}). Request aborted. {1}", uri, ex); return(null); } HttpResponseMessage response2 = null; if (await IsXrdsDocumentAsync(response)) { Logger.Yadis.Debug("An XRDS response was received from GET at user-supplied identifier."); Reporting.RecordEventOccurrence("Yadis", "XRDS in initial response"); response2 = response; } else { IEnumerable <string> uriStrings; string uriString = null; if (response.Headers.TryGetValues(HeaderName, out uriStrings)) { uriString = uriStrings.FirstOrDefault(); } Uri url = null; if (uriString != null) { if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) { Logger.Yadis.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); Reporting.RecordEventOccurrence("Yadis", "XRDS referenced in HTTP header"); } } var contentType = response.Content.Headers.ContentType; if (url == null && contentType != null && (contentType.MediaType == ContentTypes.Html || contentType.MediaType == ContentTypes.XHtml)) { url = FindYadisDocumentLocationInHtmlMetaTags(await response.Content.ReadAsStringAsync()); if (url != null) { Logger.Yadis.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); Reporting.RecordEventOccurrence("Yadis", "XRDS referenced in HTML"); } } if (url != null) { if (!requireSsl || string.Equals(url.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { response2 = await RequestAsync(url, requireSsl, hostFactories, cancellationToken, ContentTypes.Xrds); if (response2.StatusCode != HttpStatusCode.OK) { Logger.Yadis.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response2.StatusCode, response2.StatusCode, uri); } } else { Logger.Yadis.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); } } } return(await DiscoveryResult.CreateAsync(uri, response, response2)); }