diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-07-19 20:29:12 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-07-19 20:29:12 -0700 |
commit | 558e51ae4b40e79b7d681a94d9b14afba846db19 (patch) | |
tree | 8c3bfe2c3626a008ce7443a38db878d732488972 | |
parent | e6a4257d2681e8988a981bec18d03348ea31a630 (diff) | |
parent | a45aa1c270709589f406f616510447c98b6592de (diff) | |
download | DotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.zip DotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.tar.gz DotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.tar.bz2 |
Merge branch 'v3.3' into v3.4
Conflicts:
samples/DotNetOpenAuth.ApplicationBlock/Util.cs
12 files changed, 203 insertions, 10 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Util.cs b/samples/DotNetOpenAuth.ApplicationBlock/Util.cs index ea7da97..65505b6 100644 --- a/samples/DotNetOpenAuth.ApplicationBlock/Util.cs +++ b/samples/DotNetOpenAuth.ApplicationBlock/Util.cs @@ -1,10 +1,44 @@ namespace DotNetOpenAuth.ApplicationBlock { using System; using System.Collections.Generic; + using System.Diagnostics; using System.IO; + using System.Net; using DotNetOpenAuth.Messaging; - internal static class Util { + public static class Util { + /// <summary> + /// Pseudo-random data generator. + /// </summary> + internal static readonly Random NonCryptoRandomDataGenerator = new Random(); + + /// <summary> + /// Sets the channel's outgoing HTTP requests to use default network credentials. + /// </summary> + /// <param name="channel">The channel to modify.</param> + public static void UseDefaultNetworkCredentialsOnOutgoingHttpRequests(this Channel channel) + { + Debug.Assert(!(channel.WebRequestHandler is WrappingWebRequestHandler), "Wrapping an already wrapped web request handler. This is legal, but highly suspect of a bug as you don't want to wrap the same channel repeatedly to apply the same effect."); + AddOutgoingHttpRequestTransform(channel, http => http.Credentials = CredentialCache.DefaultNetworkCredentials); + } + + /// <summary> + /// Adds some action to any outgoing HTTP request on this channel. + /// </summary> + /// <param name="channel">The channel's whose outgoing HTTP requests should be modified.</param> + /// <param name="action">The action to perform on outgoing HTTP requests.</param> + internal static void AddOutgoingHttpRequestTransform(this Channel channel, Action<HttpWebRequest> action) { + if (channel == null) { + throw new ArgumentNullException("channel"); + } + + if (action == null) { + throw new ArgumentNullException("action"); + } + + channel.WebRequestHandler = new WrappingWebRequestHandler(channel.WebRequestHandler, action); + } + /// <summary> /// Enumerates through the individual set bits in a flag enum. /// </summary> @@ -72,5 +106,154 @@ return totalCopiedBytes; } + + /// <summary> + /// Wraps some instance of a web request handler in order to perform some extra operation on all + /// outgoing HTTP requests. + /// </summary> + private class WrappingWebRequestHandler : IDirectWebRequestHandler + { + /// <summary> + /// The handler being wrapped. + /// </summary> + private readonly IDirectWebRequestHandler wrappedHandler; + + /// <summary> + /// The action to perform on outgoing HTTP requests. + /// </summary> + private readonly Action<HttpWebRequest> action; + + /// <summary> + /// Initializes a new instance of the <see cref="WrappingWebRequestHandler"/> class. + /// </summary> + /// <param name="wrappedHandler">The HTTP handler to wrap.</param> + /// <param name="action">The action to perform on outgoing HTTP requests.</param> + internal WrappingWebRequestHandler(IDirectWebRequestHandler wrappedHandler, Action<HttpWebRequest> action) + { + if (wrappedHandler == null) { + throw new ArgumentNullException("wrappedHandler"); + } + + if (action == null) { + throw new ArgumentNullException("action"); + } + + this.wrappedHandler = wrappedHandler; + this.action = action; + } + + #region Implementation of IDirectWebRequestHandler + + /// <summary> + /// Determines whether this instance can support the specified options. + /// </summary> + /// <param name="options">The set of options that might be given in a subsequent web request.</param> + /// <returns> + /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>. + /// </returns> + public bool CanSupport(DirectWebRequestOptions options) + { + return this.wrappedHandler.CanSupport(options); + } + + /// <summary> + /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. + /// </summary> + /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> + /// <returns> + /// The stream the caller should write out the entity data to. + /// </returns> + /// <exception cref="ProtocolException">Thrown for any network error.</exception> + /// <remarks> + /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> + /// and any other appropriate properties <i>before</i> calling this method. + /// Callers <i>must</i> close and dispose of the request stream when they are done + /// writing to it to avoid taking up the connection too long and causing long waits on + /// subsequent requests.</para> + /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a + /// <see cref="ProtocolException"/> to abstract away the transport and provide + /// a single exception type for hosts to catch.</para> + /// </remarks> + public Stream GetRequestStream(HttpWebRequest request) + { + this.action(request); + return wrappedHandler.GetRequestStream(request); + } + + /// <summary> + /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity. + /// </summary> + /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param> + /// <param name="options">The options to apply to this web request.</param> + /// <returns> + /// The stream the caller should write out the entity data to. + /// </returns> + /// <exception cref="ProtocolException">Thrown for any network error.</exception> + /// <remarks> + /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/> + /// and any other appropriate properties <i>before</i> calling this method. + /// Callers <i>must</i> close and dispose of the request stream when they are done + /// writing to it to avoid taking up the connection too long and causing long waits on + /// subsequent requests.</para> + /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a + /// <see cref="ProtocolException"/> to abstract away the transport and provide + /// a single exception type for hosts to catch.</para> + /// </remarks> + public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) + { + this.action(request); + return wrappedHandler.GetRequestStream(request, options); + } + + /// <summary> + /// Processes an <see cref="HttpWebRequest"/> and converts the + /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. + /// </summary> + /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> + /// <returns>An instance of <see cref="IncomingWebResponse"/> describing the response.</returns> + /// <exception cref="ProtocolException">Thrown for any network error.</exception> + /// <remarks> + /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a + /// <see cref="ProtocolException"/> to abstract away the transport and provide + /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> + /// value, if set, should be Closed before throwing.</para> + /// </remarks> + public IncomingWebResponse GetResponse(HttpWebRequest request) + { + // If the request has an entity, the action would have already been processed in GetRequestStream. + if (request.Method == "GET") + { + this.action(request); + } + + return wrappedHandler.GetResponse(request); + } + + /// <summary> + /// Processes an <see cref="HttpWebRequest"/> and converts the + /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance. + /// </summary> + /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> + /// <param name="options">The options to apply to this web request.</param> + /// <returns>An instance of <see cref="IncomingWebResponse"/> describing the response.</returns> + /// <exception cref="ProtocolException">Thrown for any network error.</exception> + /// <remarks> + /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a + /// <see cref="ProtocolException"/> to abstract away the transport and provide + /// a single exception type for hosts to catch. The <see cref="WebException.Response"/> + /// value, if set, should be Closed before throwing.</para> + /// </remarks> + public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) + { + // If the request has an entity, the action would have already been processed in GetRequestStream. + if (request.Method == "GET") { + this.action(request); + } + + return wrappedHandler.GetResponse(request, options); + } + + #endregion + } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs index 35672d7..e11854e 100644 --- a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs +++ b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs @@ -12,6 +12,7 @@ namespace DotNetOpenAuth.Test.Mocks { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; + using DotNetOpenAuth.Test.OAuth; internal class InMemoryTokenManager : IConsumerTokenManager, IServiceProviderTokenManager { private KeyedCollectionDelegate<string, ConsumerInfo> consumers = new KeyedCollectionDelegate<string, ConsumerInfo>(c => c.Key); diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs index 036f8ec..e1ff959 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test.ChannelElements { +namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; using DotNetOpenAuth.Test.Mocks; diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs index f78f4e1..dd6738f 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test.ChannelElements { +namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -359,6 +359,7 @@ namespace DotNetOpenAuth.Test.ChannelElements { { "Name", "Andrew" }, { "Location", "http://hostb/pathB" }, { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) }, + { "realm" , "someValue" }, }; IProtocolMessage requestMessage = this.channel.ReadFromRequest(CreateHttpRequestInfo(scheme, fields)); Assert.IsNotNull(requestMessage); @@ -367,6 +368,12 @@ namespace DotNetOpenAuth.Test.ChannelElements { Assert.AreEqual(15, testMessage.Age); Assert.AreEqual("Andrew", testMessage.Name); Assert.AreEqual("http://hostb/pathB", testMessage.Location.AbsoluteUri); + if (scheme == HttpDeliveryMethods.AuthorizationHeaderRequest) { + // The realm value should be ignored in the authorization header + Assert.IsFalse(((IMessage)testMessage).ExtraData.ContainsKey("realm")); + } else { + Assert.AreEqual("someValue", ((IMessage)testMessage).ExtraData["realm"]); + } } } } diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs index b81eefa..c497495 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test.ChannelElements { +namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs index 86add22..2ef7e9a 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test.ChannelElements { +namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OAuth; diff --git a/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs b/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs index 625f416..89105ef 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test { +namespace DotNetOpenAuth.Test.OAuth { /// <summary> /// Information necessary to initialize a <see cref="Consumer"/>, /// and to tell a <see cref="ServiceProvider"/> about it. diff --git a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs index 5967a03..972dd2a 100644 --- a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs +++ b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test { +namespace DotNetOpenAuth.Test.OAuth { using System; using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; diff --git a/src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs b/src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs index f866990..6fac69e 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test { +namespace DotNetOpenAuth.Test.OAuth { using DotNetOpenAuth.OAuth; using NUnit.Framework; diff --git a/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs b/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs index 4ed1c74..1aa401d 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs @@ -4,7 +4,7 @@ // </copyright> //----------------------------------------------------------------------- -namespace DotNetOpenAuth.Test { +namespace DotNetOpenAuth.Test.OAuth { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs index dc59b56..f2d69f5 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs @@ -139,6 +139,8 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { } } } + + fields.Remove("realm"); // ignore the realm parameter, since we don't use it, and it must be omitted from signature base string. } // Scrape the entity diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index 36ec784..305976a 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -36,7 +36,7 @@ namespace DotNetOpenAuth.OpenId { /// <summary> /// Gets the original string that was normalized to create this Identifier. /// </summary> - public string OriginalString { get; private set; } + internal string OriginalString { get; private set; } /// <summary> /// Gets the Identifier in the form in which it should be serialized. |