diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-03-15 20:06:01 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-03-15 20:06:01 -0700 |
commit | 68003ef194ed798bce7a4c81f48c210b4bc1bd5e (patch) | |
tree | e537cd25995ac7859f4e83e6a5ac64087feb9c51 | |
parent | 61a9b1383ed26b461b03c74341b82be6bb39ebfb (diff) | |
download | DotNetOpenAuth-68003ef194ed798bce7a4c81f48c210b4bc1bd5e.zip DotNetOpenAuth-68003ef194ed798bce7a4c81f48c210b4bc1bd5e.tar.gz DotNetOpenAuth-68003ef194ed798bce7a4c81f48c210b4bc1bd5e.tar.bz2 |
Fixed XRDS discovery no longer prevents HTML discovery from succeeding.
Fixes Trac #186
7 files changed, 71 insertions, 11 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index 6540714..6355d59 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -373,6 +373,12 @@ <Install>true</Install> </BootstrapperPackage> </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20provWithEmptyXrds.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20provWithBadXrds.html" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> </Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithBadXrds.html b/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithBadXrds.html new file mode 100644 index 0000000..e695116 --- /dev/null +++ b/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithBadXrds.html @@ -0,0 +1,10 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Untitled Page</title> + <meta http-equiv="X-XRDS-Location" content="http://localhost/xrds-notfound.xml"/> + <link rel="openid2.provider" href="http://a/b" /> +</head> +<body> +</body> +</html> diff --git a/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithEmptyXrds.html b/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithEmptyXrds.html new file mode 100644 index 0000000..97ad7dc --- /dev/null +++ b/src/DotNetOpenAuth.Test/OpenId/Discovery/htmldiscovery/html20provWithEmptyXrds.html @@ -0,0 +1,10 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Untitled Page</title> + <meta http-equiv="X-XRDS-Location" content="http://localhost/xrds-irrelevant.xml"/> + <link rel="openid2.provider" href="http://a/b" /> +</head> +<body> +</body> +</html> diff --git a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs index 7b12a1d..1050b4b 100644 --- a/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/DiscoveryServices/UriDiscoveryServiceTests.cs @@ -179,6 +179,23 @@ namespace DotNetOpenAuth.Test.OpenId.DiscoveryServices { } /// <summary> + /// Verifies HTML discovery proceeds if an XRDS document is referenced that doesn't contain OpenID endpoints. + /// </summary> + [TestCase] + public void HtmlDiscoveryProceedsIfXrdsIsEmpty() { + this.MockResponder.RegisterMockResponse(new Uri("http://localhost/xrds-irrelevant.xml"), "application/xrds+xml", LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds-irrelevant.xml")); + this.DiscoverHtml("html20provWithEmptyXrds", ProtocolVersion.V20, null, "http://a/b"); + } + + /// <summary> + /// Verifies HTML discovery proceeds if the XRDS that is referenced cannot be found. + /// </summary> + [TestCase] + public void HtmlDiscoveryProceedsIfXrdsIsBadOrMissing() { + this.DiscoverHtml("html20provWithBadXrds", ProtocolVersion.V20, null, "http://a/b"); + } + + /// <summary> /// Verifies that a dual identifier yields only one service endpoint by default. /// </summary> [TestCase] diff --git a/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs b/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs index f017d9f..7d17fd9 100644 --- a/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs +++ b/src/DotNetOpenAuth/OpenId/UriDiscoveryService.cs @@ -67,6 +67,7 @@ namespace DotNetOpenAuth.OpenId { // Failing YADIS discovery of an XRDS document, we try HTML discovery. if (endpoints.Count == 0) { + yadisResult.TryRevertToHtmlResponse(); var htmlEndpoints = new List<IdentifierDiscoveryResult>(DiscoverFromHtml(yadisResult.NormalizedUri, uriIdentifier, yadisResult.ResponseText)); if (htmlEndpoints.Any()) { Logger.Yadis.DebugFormat("Total services discovered in HTML: {0}", htmlEndpoints.Count); diff --git a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs index 01dae40..06c6fc7 100644 --- a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs +++ b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs @@ -17,6 +17,12 @@ namespace DotNetOpenAuth.Yadis { /// </summary> internal class DiscoveryResult { /// <summary> + /// The original web response, backed up here if the final web response is the preferred response to use + /// in case it turns out to not work out. + /// </summary> + private CachedDirectWebResponse htmlFallback; + + /// <summary> /// Initializes a new instance of the <see cref="DiscoveryResult"/> class. /// </summary> /// <param name="requestUri">The user-supplied identifier.</param> @@ -25,10 +31,8 @@ namespace DotNetOpenAuth.Yadis { public DiscoveryResult(Uri requestUri, CachedDirectWebResponse initialResponse, CachedDirectWebResponse finalResponse) { this.RequestUri = requestUri; this.NormalizedUri = initialResponse.FinalUri; - if (finalResponse == null) { - this.ContentType = initialResponse.ContentType; - this.ResponseText = initialResponse.GetResponseString(); - this.IsXrds = this.ContentType != null && this.ContentType.MediaType == ContentTypes.Xrds; + if (finalResponse == null || finalResponse.Status != System.Net.HttpStatusCode.OK) { + this.ApplyHtmlResponse(initialResponse); } else { this.ContentType = finalResponse.ContentType; this.ResponseText = finalResponse.GetResponseString(); @@ -36,6 +40,9 @@ namespace DotNetOpenAuth.Yadis { if (initialResponse != finalResponse) { this.YadisLocation = finalResponse.RequestUri; } + + // Back up the initial HTML response in case the XRDS is not useful. + this.htmlFallback = initialResponse; } } @@ -77,13 +84,23 @@ namespace DotNetOpenAuth.Yadis { public bool IsXrds { get; private set; } /// <summary> - /// Gets a value indicating whether discovery resulted in an - /// XRDS document at a referred location. + /// Reverts to the HTML response after the XRDS response didn't work out. + /// </summary> + internal void TryRevertToHtmlResponse() { + if (this.htmlFallback != null) { + this.ApplyHtmlResponse(this.htmlFallback); + this.htmlFallback = null; + } + } + + /// <summary> + /// Applies the HTML response to the object. /// </summary> - /// <value><c>true</c> if the response to the userSuppliedIdentifier - /// pointed to a different URL for the XRDS document.</value> - public bool UsedYadisLocation { - get { return this.YadisLocation != null; } + /// <param name="initialResponse">The initial response.</param> + private void ApplyHtmlResponse(CachedDirectWebResponse initialResponse) { + this.ContentType = initialResponse.ContentType; + this.ResponseText = initialResponse.GetResponseString(); + this.IsXrds = this.ContentType != null && this.ContentType.MediaType == ContentTypes.Xrds; } } } diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs index f1c8be3..7882797 100644 --- a/src/DotNetOpenAuth/Yadis/Yadis.cs +++ b/src/DotNetOpenAuth/Yadis/Yadis.cs @@ -96,7 +96,6 @@ namespace DotNetOpenAuth.Yadis { response2 = Request(requestHandler, url, requireSsl, ContentTypes.Xrds).GetSnapshot(MaximumResultToScan); if (response2.Status != HttpStatusCode.OK) { Logger.Yadis.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response2.Status, response2.Status, uri); - return null; } } else { Logger.Yadis.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); |