summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs')
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs138
1 files changed, 73 insertions, 65 deletions
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs
index 910272e..fb4006c 100644
--- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/HostMetaDiscoveryService.cs
@@ -71,6 +71,12 @@ namespace DotNetOpenAuth.OpenId {
this.TrustedHostMetaProxies = new List<HostMetaProxy>();
}
+ /// <summary>
+ /// Gets or sets the host factories used by this instance.
+ /// </summary>
+ /// <value>
+ /// The host factories.
+ /// </value>
public IHostFactories HostFactories { get; set; }
/// <summary>
@@ -108,8 +114,7 @@ namespace DotNetOpenAuth.OpenId {
/// Performs discovery on the specified identifier.
/// </summary>
/// <param name="identifier">The identifier to perform discovery on.</param>
- /// <param name="requestHandler">The means to place outgoing HTTP requests.</param>
- /// <param name="abortDiscoveryChain">if set to <c>true</c>, no further discovery services will be called for this identifier.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty.
/// </returns>
@@ -182,43 +187,6 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
- /// Gets the services for an identifier that are described by an external XRDS document.
- /// </summary>
- /// <param name="xrds">The XRD elements to search for described-by services.</param>
- /// <param name="identifier">The identifier under discovery.</param>
- /// <param name="requestHandler">The request handler.</param>
- /// <returns>The discovered services.</returns>
- private async Task<IEnumerable<IdentifierDiscoveryResult>> GetExternalServicesAsync(IEnumerable<XrdElement> xrds, UriIdentifier identifier, CancellationToken cancellationToken) {
- Requires.NotNull(xrds, "xrds");
- Requires.NotNull(identifier, "identifier");
-
- var results = new List<IdentifierDiscoveryResult>();
- foreach (var serviceElement in GetDescribedByServices(xrds)) {
- var templateNode = serviceElement.Node.SelectSingleNode("google:URITemplate", serviceElement.XmlNamespaceResolver);
- var nextAuthorityNode = serviceElement.Node.SelectSingleNode("google:NextAuthority", serviceElement.XmlNamespaceResolver);
- if (templateNode != null) {
- Uri externalLocation = new Uri(templateNode.Value.Trim().Replace("{%uri}", Uri.EscapeDataString(identifier.Uri.AbsoluteUri)));
- string nextAuthority = nextAuthorityNode != null ? nextAuthorityNode.Value.Trim() : identifier.Uri.Host;
- try {
- using (var externalXrdsResponse = await this.GetXrdsResponseAsync(identifier, externalLocation, cancellationToken)) {
- var readerSettings = MessagingUtilities.CreateUntrustedXmlReaderSettings();
- var responseStream = await externalXrdsResponse.Content.ReadAsStreamAsync();
- XrdsDocument externalXrds = new XrdsDocument(XmlReader.Create(responseStream, readerSettings));
- await ValidateXmlDSigAsync(externalXrds, identifier, externalXrdsResponse, nextAuthority);
- results.AddRange(GetXrdElements(externalXrds, identifier).CreateServiceEndpoints(identifier, identifier));
- }
- } catch (ProtocolException ex) {
- Logger.Yadis.WarnFormat("HTTP GET error while retrieving described-by XRDS document {0}: {1}", externalLocation.AbsoluteUri, ex);
- } catch (XmlException ex) {
- Logger.Yadis.ErrorFormat("Error while parsing described-by XRDS document {0}: {1}", externalLocation.AbsoluteUri, ex);
- }
- }
- }
-
- return results;
- }
-
- /// <summary>
/// Validates the XML digital signature on an XRDS document.
/// </summary>
/// <param name="document">The XRDS document whose signature should be validated.</param>
@@ -291,11 +259,50 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
+ /// Gets the services for an identifier that are described by an external XRDS document.
+ /// </summary>
+ /// <param name="xrds">The XRD elements to search for described-by services.</param>
+ /// <param name="identifier">The identifier under discovery.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The discovered services.
+ /// </returns>
+ private async Task<IEnumerable<IdentifierDiscoveryResult>> GetExternalServicesAsync(IEnumerable<XrdElement> xrds, UriIdentifier identifier, CancellationToken cancellationToken) {
+ Requires.NotNull(xrds, "xrds");
+ Requires.NotNull(identifier, "identifier");
+
+ var results = new List<IdentifierDiscoveryResult>();
+ foreach (var serviceElement in GetDescribedByServices(xrds)) {
+ var templateNode = serviceElement.Node.SelectSingleNode("google:URITemplate", serviceElement.XmlNamespaceResolver);
+ var nextAuthorityNode = serviceElement.Node.SelectSingleNode("google:NextAuthority", serviceElement.XmlNamespaceResolver);
+ if (templateNode != null) {
+ Uri externalLocation = new Uri(templateNode.Value.Trim().Replace("{%uri}", Uri.EscapeDataString(identifier.Uri.AbsoluteUri)));
+ string nextAuthority = nextAuthorityNode != null ? nextAuthorityNode.Value.Trim() : identifier.Uri.Host;
+ try {
+ using (var externalXrdsResponse = await this.GetXrdsResponseAsync(identifier, externalLocation, cancellationToken)) {
+ var readerSettings = MessagingUtilities.CreateUntrustedXmlReaderSettings();
+ var responseStream = await externalXrdsResponse.Content.ReadAsStreamAsync();
+ XrdsDocument externalXrds = new XrdsDocument(XmlReader.Create(responseStream, readerSettings));
+ await ValidateXmlDSigAsync(externalXrds, identifier, externalXrdsResponse, nextAuthority);
+ results.AddRange(GetXrdElements(externalXrds, identifier).CreateServiceEndpoints(identifier, identifier));
+ }
+ } catch (ProtocolException ex) {
+ Logger.Yadis.WarnFormat("HTTP GET error while retrieving described-by XRDS document {0}: {1}", externalLocation.AbsoluteUri, ex);
+ } catch (XmlException ex) {
+ Logger.Yadis.ErrorFormat("Error while parsing described-by XRDS document {0}: {1}", externalLocation.AbsoluteUri, ex);
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /// <summary>
/// Gets the XRDS HTTP response for a given identifier.
/// </summary>
/// <param name="identifier">The identifier.</param>
- /// <param name="requestHandler">The request handler.</param>
/// <param name="xrdsLocation">The location of the XRDS document to retrieve.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A HTTP response carrying an XRDS document.
/// </returns>
@@ -369,9 +376,10 @@ namespace DotNetOpenAuth.OpenId {
/// Gets the XRDS HTTP response for a given identifier.
/// </summary>
/// <param name="identifier">The identifier.</param>
- /// <param name="requestHandler">The request handler.</param>
- /// <param name="signingHost">The host name on the certificate that should be used to verify the signature in the XRDS.</param>
- /// <returns>A HTTP response carrying an XRDS document, or <c>null</c> if one could not be obtained.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// A HTTP response carrying an XRDS document, or <c>null</c> if one could not be obtained.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if the XRDS document could not be obtained.</exception>
private async Task<ResultWithSigningHost<HttpResponseMessage>> GetXrdsResponseAsync(UriIdentifier identifier, CancellationToken cancellationToken) {
Requires.NotNull(identifier, "identifier");
@@ -389,9 +397,10 @@ namespace DotNetOpenAuth.OpenId {
/// Gets the location of the XRDS document that describes a given identifier.
/// </summary>
/// <param name="identifier">The identifier under discovery.</param>
- /// <param name="requestHandler">The request handler.</param>
- /// <param name="signingHost">The host name on the certificate that should be used to verify the signature in the XRDS.</param>
- /// <returns>An absolute URI, or <c>null</c> if one could not be determined.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// An absolute URI, or <c>null</c> if one could not be determined.
+ /// </returns>
private async Task<ResultWithSigningHost<Uri>> GetXrdsLocationAsync(UriIdentifier identifier, CancellationToken cancellationToken) {
Requires.NotNull(identifier, "identifier");
@@ -419,8 +428,7 @@ namespace DotNetOpenAuth.OpenId {
/// Gets the host-meta for a given identifier.
/// </summary>
/// <param name="identifier">The identifier.</param>
- /// <param name="requestHandler">The request handler.</param>
- /// <param name="signingHost">The host name on the certificate that should be used to verify the signature in the XRDS.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The host-meta response, or <c>null</c> if no host-meta document could be obtained.
/// </returns>
@@ -471,6 +479,23 @@ namespace DotNetOpenAuth.OpenId {
return result;
}
+ private struct ResultWithSigningHost<T> : IDisposable {
+ internal ResultWithSigningHost(T result, string signingHost)
+ : this() {
+ this.Result = result;
+ this.SigningHost = signingHost;
+ }
+
+ public T Result { get; private set; }
+
+ public string SigningHost { get; private set; }
+
+ public void Dispose() {
+ var disposable = this.Result as IDisposable;
+ disposable.DisposeIfNotNull();
+ }
+ }
+
/// <summary>
/// A description of a web server that hosts host-meta documents.
/// </summary>
@@ -554,22 +579,5 @@ namespace DotNetOpenAuth.OpenId {
return this.ProxyFormat.GetHashCode();
}
}
-
- private struct ResultWithSigningHost<T> : IDisposable {
- internal ResultWithSigningHost(T result, string signingHost)
- : this() {
- this.Result = result;
- this.SigningHost = signingHost;
- }
-
- public T Result { get; private set; }
-
- public string SigningHost { get; private set; }
-
- public void Dispose() {
- var disposable = this.Result as IDisposable;
- disposable.DisposeIfNotNull();
- }
- }
}
}