summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-07-19 20:29:12 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2010-07-19 20:29:12 -0700
commit558e51ae4b40e79b7d681a94d9b14afba846db19 (patch)
tree8c3bfe2c3626a008ce7443a38db878d732488972
parente6a4257d2681e8988a981bec18d03348ea31a630 (diff)
parenta45aa1c270709589f406f616510447c98b6592de (diff)
downloadDotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.zip
DotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.tar.gz
DotNetOpenAuth-558e51ae4b40e79b7d681a94d9b14afba846db19.tar.bz2
Merge branch 'v3.3' into v3.4
Conflicts: samples/DotNetOpenAuth.ApplicationBlock/Util.cs
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Util.cs185
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs1
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs9
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/Identifier.cs2
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.