Skip to content
This repository has been archived by the owner on Mar 20, 2019. It is now read-only.

Commit

Permalink
Merge branch 'v3.2' into v3.3
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Jul 20, 2010
2 parents 7c480e5 + acf57b0 commit a45aa1c
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 14 deletions.
185 changes: 184 additions & 1 deletion samples/DotNetOpenAuth.ApplicationBlock/Util.cs
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -72,5 +106,154 @@ internal static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytes

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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ public void RequiredNonNullableStruct() {

[TestMethod]
public void OptionalNullableStruct() {
this.ParameterizedMessageTypeTest(typeof(MessageWithNullableOptionalStruct));
var message = new MessageWithNullableOptionalStruct();
var part = this.ParameterizedMessageTypeTest(message.GetType());

Assert.IsNull(part.GetValue(message));
part.SetValue(message, "3");
Assert.AreEqual("3", part.GetValue(message));
}

[TestMethod]
Expand Down
1 change: 1 addition & 0 deletions src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test.ChannelElements {
namespace DotNetOpenAuth.Test.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
Expand Down Expand Up @@ -362,6 +362,7 @@ private void ParameterizedReceiveTest(HttpDeliveryMethods scheme) {
{ "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);
Expand All @@ -370,6 +371,12 @@ private void ParameterizedReceiveTest(HttpDeliveryMethods scheme) {
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"]);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test.ChannelElements {
namespace DotNetOpenAuth.Test.OAuth.ChannelElements {
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test.ChannelElements {
namespace DotNetOpenAuth.Test.OAuth.ChannelElements {
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Reflection;
using DotNetOpenAuth.OAuth;
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetOpenAuth.Test/OAuth/ConsumerDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test {
namespace DotNetOpenAuth.Test.OAuth {
using System;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetOpenAuth.Test/OAuth/ProtocolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test {
namespace DotNetOpenAuth.Test.OAuth {
using DotNetOpenAuth.OAuth;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test {
namespace DotNetOpenAuth.Test.OAuth {
using System;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
Expand Down
24 changes: 20 additions & 4 deletions src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,25 @@ internal MessagePart(MemberInfo member, MessagePartAttribute attribute) {
Contract.Assume(this.memberDeclaredType != null); // CC missing PropertyInfo.PropertyType ensures result != null
if (attribute.Encoder == null) {
if (!converters.TryGetValue(this.memberDeclaredType, out this.converter)) {
this.converter = new ValueMapping(
obj => obj != null ? obj.ToString() : null,
str => str != null ? Convert.ChangeType(str, this.memberDeclaredType, CultureInfo.InvariantCulture) : null);
if (this.memberDeclaredType.IsGenericType &&
this.memberDeclaredType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
// It's a nullable type. Try again to look up an appropriate converter for the underlying type.
Type underlyingType = Nullable.GetUnderlyingType(this.memberDeclaredType);
ValueMapping underlyingMapping;
if (converters.TryGetValue(underlyingType, out underlyingMapping)) {
this.converter = new ValueMapping(
underlyingMapping.ValueToString,
str => str != null ? underlyingMapping.StringToValue(str) : null);
} else {
this.converter = new ValueMapping(
obj => obj != null ? obj.ToString() : null,
str => str != null ? Convert.ChangeType(str, underlyingType, CultureInfo.InvariantCulture) : null);
}
} else {
this.converter = new ValueMapping(
obj => obj != null ? obj.ToString() : null,
str => str != null ? Convert.ChangeType(str, this.memberDeclaredType, CultureInfo.InvariantCulture) : null);
}
}
} else {
this.converter = new ValueMapping(GetEncoder(attribute.Encoder));
Expand Down Expand Up @@ -252,7 +268,7 @@ private static object DeriveDefaultValue(Type type) {
}

/// <summary>
/// Adds a pair of type conversion functions to the static converstion map.
/// Adds a pair of type conversion functions to the static conversion map.
/// </summary>
/// <typeparam name="T">The custom type to convert to and from strings.</typeparam>
/// <param name="toString">The function to convert the custom type to a string.</param>
Expand Down
2 changes: 2 additions & 0 deletions src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestInfo
}
}
}

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
Expand Down

0 comments on commit a45aa1c

Please sign in to comment.