diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2013-03-26 11:19:06 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2013-03-26 11:19:06 -0700 |
commit | 3d37ff45cab6838d80b22e6b782a0b9b4c2f4aeb (patch) | |
tree | c15816c3d7f6e74334553f2ff98605ce1c22c538 /src/DotNetOpenAuth.Test/Mocks | |
parent | 5e9014f36b2d53b8e419918675df636540ea24e2 (diff) | |
parent | e6f7409f4caceb7bc2a5b4ddbcb1a4097af340f2 (diff) | |
download | DotNetOpenAuth-3d37ff45cab6838d80b22e6b782a0b9b4c2f4aeb.zip DotNetOpenAuth-3d37ff45cab6838d80b22e6b782a0b9b4c2f4aeb.tar.gz DotNetOpenAuth-3d37ff45cab6838d80b22e6b782a0b9b4c2f4aeb.tar.bz2 |
Move to HttpClient throughout library.
Diffstat (limited to 'src/DotNetOpenAuth.Test/Mocks')
18 files changed, 138 insertions, 1283 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs deleted file mode 100644 index 475f4b5..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs +++ /dev/null @@ -1,348 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingChannel.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Text; - using System.Threading; - using System.Web; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.Messaging.Reflection; - using DotNetOpenAuth.Test.OpenId; - using NUnit.Framework; - using Validation; - - internal class CoordinatingChannel : Channel { - /// <summary> - /// A lock to use when checking and setting the <see cref="waitingForMessage"/> - /// or the <see cref="simulationCompleted"/> fields. - /// </summary> - /// <remarks> - /// This is a static member so that all coordinating channels share a lock - /// since they peak at each others fields. - /// </remarks> - private static readonly object waitingForMessageCoordinationLock = new object(); - - /// <summary> - /// The original product channel whose behavior is being modified to work - /// better in automated testing. - /// </summary> - private Channel wrappedChannel; - - /// <summary> - /// A flag set to true when this party in a two-party test has completed - /// its part of the testing. - /// </summary> - private bool simulationCompleted; - - /// <summary> - /// A thread-coordinating signal that is set when another thread has a - /// message ready for this channel to receive. - /// </summary> - private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false); - - /// <summary> - /// A thread-coordinating signal that is set briefly by this thread whenever - /// a message is picked up. - /// </summary> - private EventWaitHandle messageReceivedSignal = new AutoResetEvent(false); - - /// <summary> - /// A flag used to indicate when this channel is waiting for a message - /// to arrive. - /// </summary> - private bool waitingForMessage; - - /// <summary> - /// An incoming message that has been posted by a remote channel and - /// is waiting for receipt by this channel. - /// </summary> - private IDictionary<string, string> incomingMessage; - - /// <summary> - /// The recipient URL of the <see cref="incomingMessage"/>, where applicable. - /// </summary> - private MessageReceivingEndpoint incomingMessageRecipient; - - /// <summary> - /// The headers of the <see cref="incomingMessage"/>, where applicable. - /// </summary> - private WebHeaderCollection incomingMessageHttpHeaders; - - /// <summary> - /// A delegate that gets a chance to peak at and fiddle with all - /// incoming messages. - /// </summary> - private Action<IProtocolMessage> incomingMessageFilter; - - /// <summary> - /// A delegate that gets a chance to peak at and fiddle with all - /// outgoing messages. - /// </summary> - private Action<IProtocolMessage> outgoingMessageFilter; - - /// <summary> - /// The simulated clients cookies. - /// </summary> - private HttpCookieCollection cookies = new HttpCookieCollection(); - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingChannel"/> class. - /// </summary> - /// <param name="wrappedChannel">The wrapped channel. Must not be null.</param> - /// <param name="incomingMessageFilter">The incoming message filter. May be null.</param> - /// <param name="outgoingMessageFilter">The outgoing message filter. May be null.</param> - internal CoordinatingChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter) - : base(GetMessageFactory(wrappedChannel), wrappedChannel.BindingElements.ToArray()) { - Requires.NotNull(wrappedChannel, "wrappedChannel"); - - this.wrappedChannel = wrappedChannel; - this.incomingMessageFilter = incomingMessageFilter; - this.outgoingMessageFilter = outgoingMessageFilter; - - // Preserve any customized binding element ordering. - this.CustomizeBindingElementOrder(this.wrappedChannel.OutgoingBindingElements, this.wrappedChannel.IncomingBindingElements); - } - - /// <summary> - /// Gets or sets the coordinating channel used by the other party. - /// </summary> - internal CoordinatingChannel RemoteChannel { get; set; } - - /// <summary> - /// Indicates that the simulation that uses this channel has completed work. - /// </summary> - /// <remarks> - /// Calling this method is not strictly necessary, but it gives the channel - /// coordination a chance to recognize when another channel is left dangling - /// waiting for a message from another channel that may never come. - /// </remarks> - internal void Close() { - lock (waitingForMessageCoordinationLock) { - this.simulationCompleted = true; - if (this.RemoteChannel.waitingForMessage && this.RemoteChannel.incomingMessage == null) { - TestUtilities.TestLogger.Debug("CoordinatingChannel is closing while remote channel is waiting for an incoming message. Signaling channel to unblock it to receive a null message."); - this.RemoteChannel.incomingMessageSignal.Set(); - } - - this.Dispose(); - } - } - - /// <summary> - /// Replays the specified message as if it were received again. - /// </summary> - /// <param name="message">The message to replay.</param> - internal void Replay(IProtocolMessage message) { - this.ProcessIncomingMessage(this.CloneSerializedParts(message)); - } - - /// <summary> - /// Called from a remote party's thread to post a message to this channel for processing. - /// </summary> - /// <param name="message">The message that this channel should receive. This message will be cloned.</param> - internal void PostMessage(IProtocolMessage message) { - if (this.incomingMessage != null) { - // The remote party hasn't picked up the last message we sent them. - // Wait for a short period for them to pick it up before failing. - TestBase.TestLogger.Warn("We're blocked waiting to send a message to the remote party and they haven't processed the last message we sent them."); - this.RemoteChannel.messageReceivedSignal.WaitOne(500); - } - ErrorUtilities.VerifyInternal(this.incomingMessage == null, "Oops, a message is already waiting for the remote party!"); - this.incomingMessage = this.MessageDescriptions.GetAccessor(message).Serialize(); - var directedMessage = message as IDirectedProtocolMessage; - this.incomingMessageRecipient = (directedMessage != null && directedMessage.Recipient != null) ? new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods) : null; - var httpMessage = message as IHttpDirectRequest; - this.incomingMessageHttpHeaders = (httpMessage != null) ? httpMessage.Headers.Clone() : null; - this.incomingMessageSignal.Set(); - } - - internal void SaveCookies(HttpCookieCollection cookies) { - Requires.NotNull(cookies, "cookies"); - foreach (string cookieName in cookies) { - var cookie = cookies[cookieName]; - this.cookies.Set(cookie); - } - } - - protected internal override HttpRequestBase GetRequestFromContext() { - MessageReceivingEndpoint recipient; - WebHeaderCollection headers; - var messageData = this.AwaitIncomingMessage(out recipient, out headers); - CoordinatingHttpRequestInfo result; - if (messageData != null) { - result = new CoordinatingHttpRequestInfo(this, this.MessageFactory, messageData, recipient, this.cookies); - } else { - result = new CoordinatingHttpRequestInfo(recipient, this.cookies); - } - - if (headers != null) { - headers.ApplyTo(result.Headers); - } - - return result; - } - - protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) { - this.ProcessMessageFilter(request, true); - - // Drop the outgoing message in the other channel's in-slot and let them know it's there. - this.RemoteChannel.PostMessage(request); - - // Now wait for a response... - MessageReceivingEndpoint recipient; - WebHeaderCollection headers; - IDictionary<string, string> responseData = this.AwaitIncomingMessage(out recipient, out headers); - ErrorUtilities.VerifyInternal(recipient == null, "The recipient is expected to be null for direct responses."); - - // And deserialize it. - IDirectResponseProtocolMessage responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseData); - if (responseMessage == null) { - return null; - } - - var responseAccessor = this.MessageDescriptions.GetAccessor(responseMessage); - responseAccessor.Deserialize(responseData); - var responseMessageHttpRequest = responseMessage as IHttpDirectRequest; - if (headers != null && responseMessageHttpRequest != null) { - headers.ApplyTo(responseMessageHttpRequest.Headers); - } - - this.ProcessMessageFilter(responseMessage, false); - return responseMessage; - } - - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { - this.ProcessMessageFilter(response, true); - return new CoordinatingOutgoingWebResponse(response, this.RemoteChannel, this); - } - - protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) { - this.ProcessMessageFilter(message, true); - // In this mock transport, direct and indirect messages are the same. - return this.PrepareDirectResponse(message); - } - - protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) { - var mockRequest = (CoordinatingHttpRequestInfo)request; - if (mockRequest.Message != null) { - this.ProcessMessageFilter(mockRequest.Message, false); - } - - return mockRequest.Message; - } - - protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) { - return this.wrappedChannel.ReadFromResponseCoreTestHook(response); - } - - protected override void ProcessIncomingMessage(IProtocolMessage message) { - this.wrappedChannel.ProcessIncomingMessageTestHook(message); - } - - /// <summary> - /// Clones a message, instantiating the new instance using <i>this</i> channel's - /// message factory. - /// </summary> - /// <typeparam name="T">The type of message to clone.</typeparam> - /// <param name="message">The message to clone.</param> - /// <returns>The new instance of the message.</returns> - /// <remarks> - /// This Clone method should <i>not</i> be used to send message clones to the remote - /// channel since their message factory is not used. - /// </remarks> - protected virtual T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage { - Requires.NotNull(message, "message"); - - IProtocolMessage clonedMessage; - var messageAccessor = this.MessageDescriptions.GetAccessor(message); - var fields = messageAccessor.Serialize(); - - MessageReceivingEndpoint recipient = null; - var directedMessage = message as IDirectedProtocolMessage; - var directResponse = message as IDirectResponseProtocolMessage; - if (directedMessage != null && directedMessage.IsRequest()) { - if (directedMessage.Recipient != null) { - recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods); - } - - clonedMessage = this.MessageFactory.GetNewRequestMessage(recipient, fields); - } else if (directResponse != null && directResponse.IsDirectResponse()) { - clonedMessage = this.MessageFactory.GetNewResponseMessage(directResponse.OriginatingRequest, fields); - } else { - throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types."); - } - - ErrorUtilities.VerifyInternal(clonedMessage != null, "Message factory did not generate a message instance for " + message.GetType().Name); - - // Fill the cloned message with data. - var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage); - clonedMessageAccessor.Deserialize(fields); - - return (T)clonedMessage; - } - - private static IMessageFactory GetMessageFactory(Channel channel) { - Requires.NotNull(channel, "channel"); - - return channel.MessageFactoryTestHook; - } - - private IDictionary<string, string> AwaitIncomingMessage(out MessageReceivingEndpoint recipient, out WebHeaderCollection headers) { - // Special care should be taken so that we don't indefinitely - // wait for a message that may never come due to a bug in the product - // or the test. - // There are two scenarios that we need to watch out for: - // 1. Two channels are waiting to receive messages from each other. - // 2. One channel is waiting for a message that will never come because - // the remote party has already finished executing. - lock (waitingForMessageCoordinationLock) { - // It's possible that a message was just barely transmitted either to this - // or the remote channel. So it's ok for the remote channel to be waiting - // if either it or we are already about to receive a message. - ErrorUtilities.VerifyInternal(!this.RemoteChannel.waitingForMessage || this.RemoteChannel.incomingMessage != null || this.incomingMessage != null, "This channel is expecting an incoming message from another channel that is also blocked waiting for an incoming message from us!"); - - // It's permissible that the remote channel has already closed if it left a message - // for us already. - ErrorUtilities.VerifyInternal(!this.RemoteChannel.simulationCompleted || this.incomingMessage != null, "This channel is expecting an incoming message from another channel that has already been closed."); - this.waitingForMessage = true; - } - - this.incomingMessageSignal.WaitOne(); - - lock (waitingForMessageCoordinationLock) { - this.waitingForMessage = false; - var response = this.incomingMessage; - recipient = this.incomingMessageRecipient; - headers = this.incomingMessageHttpHeaders; - this.incomingMessage = null; - this.incomingMessageRecipient = null; - this.incomingMessageHttpHeaders = null; - - // Briefly signal to another thread that might be waiting for our inbox to be empty - this.messageReceivedSignal.Set(); - this.messageReceivedSignal.Reset(); - - return response; - } - } - - private void ProcessMessageFilter(IProtocolMessage message, bool outgoing) { - if (outgoing) { - if (this.outgoingMessageFilter != null) { - this.outgoingMessageFilter(message); - } - } else { - if (this.incomingMessageFilter != null) { - this.incomingMessageFilter(message); - } - } - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs deleted file mode 100644 index 497503c..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingHttpRequestInfo.cs +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingHttpRequestInfo.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Net; - using System.Web; - - using DotNetOpenAuth.Messaging; - using Validation; - - internal class CoordinatingHttpRequestInfo : HttpRequestInfo { - private readonly Channel channel; - - private readonly IDictionary<string, string> messageData; - - private readonly IMessageFactory messageFactory; - - private readonly MessageReceivingEndpoint recipient; - - private IDirectedProtocolMessage message; - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class - /// that will generate a message when the <see cref="Message"/> property getter is called. - /// </summary> - /// <param name="channel">The channel.</param> - /// <param name="messageFactory">The message factory.</param> - /// <param name="messageData">The message data.</param> - /// <param name="recipient">The recipient.</param> - /// <param name="cookies">Cookies included in the incoming request.</param> - internal CoordinatingHttpRequestInfo( - Channel channel, - IMessageFactory messageFactory, - IDictionary<string, string> messageData, - MessageReceivingEndpoint recipient, - HttpCookieCollection cookies) - : this(recipient, cookies) { - Requires.NotNull(channel, "channel"); - Requires.NotNull(messageFactory, "messageFactory"); - Requires.NotNull(messageData, "messageData"); - this.channel = channel; - this.messageData = messageData; - this.messageFactory = messageFactory; - } - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class - /// that will not generate any message. - /// </summary> - /// <param name="recipient">The recipient.</param> - /// <param name="cookies">Cookies included in the incoming request.</param> - internal CoordinatingHttpRequestInfo(MessageReceivingEndpoint recipient, HttpCookieCollection cookies) - : base(GetHttpVerb(recipient), recipient != null ? recipient.Location : new Uri("http://host/path"), cookies: cookies) { - this.recipient = recipient; - } - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingHttpRequestInfo"/> class. - /// </summary> - /// <param name="message">The message being passed in through a mock transport. May be null.</param> - /// <param name="httpMethod">The HTTP method that the incoming request came in on, whether or not <paramref name="message"/> is null.</param> - internal CoordinatingHttpRequestInfo(IDirectedProtocolMessage message, HttpDeliveryMethods httpMethod) - : base(GetHttpVerb(httpMethod), message.Recipient) { - this.message = message; - } - - /// <summary> - /// Gets the message deserialized from the remote channel. - /// </summary> - internal IDirectedProtocolMessage Message { - get { - if (this.message == null && this.messageData != null) { - var message = this.messageFactory.GetNewRequestMessage(this.recipient, this.messageData); - if (message != null) { - this.channel.MessageDescriptions.GetAccessor(message).Deserialize(this.messageData); - this.message = message; - } - } - - return this.message; - } - } - - private static string GetHttpVerb(MessageReceivingEndpoint recipient) { - if (recipient == null) { - return "GET"; - } - - return GetHttpVerb(recipient.AllowedMethods); - } - - private static string GetHttpVerb(HttpDeliveryMethods httpMethod) { - if ((httpMethod & HttpDeliveryMethods.GetRequest) != 0) { - return "GET"; - } - - if ((httpMethod & HttpDeliveryMethods.PostRequest) != 0) { - return "POST"; - } - - throw new ArgumentOutOfRangeException(); - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs deleted file mode 100644 index 463b149..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2AuthServerChannel.cs +++ /dev/null @@ -1,33 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingOAuth2AuthServerChannel.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OAuth2; - using DotNetOpenAuth.OAuth2.ChannelElements; - - internal class CoordinatingOAuth2AuthServerChannel : CoordinatingChannel, IOAuth2ChannelWithAuthorizationServer { - private OAuth2AuthorizationServerChannel wrappedChannel; - - internal CoordinatingOAuth2AuthServerChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter) - : base(wrappedChannel, incomingMessageFilter, outgoingMessageFilter) { - this.wrappedChannel = (OAuth2AuthorizationServerChannel)wrappedChannel; - } - - public IAuthorizationServerHost AuthorizationServer { - get { return this.wrappedChannel.AuthorizationServer; } - } - - public IScopeSatisfiedCheck ScopeSatisfiedCheck { - get { return this.wrappedChannel.ScopeSatisfiedCheck; } - set { this.wrappedChannel.ScopeSatisfiedCheck = value; } - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs deleted file mode 100644 index 96091ac..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingOAuth2ClientChannel.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OAuth2.ChannelElements; - - internal class CoordinatingOAuth2ClientChannel : CoordinatingChannel, IOAuth2ChannelWithClient { - private OAuth2ClientChannel wrappedChannel; - - internal CoordinatingOAuth2ClientChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter) - : base(wrappedChannel, incomingMessageFilter, outgoingMessageFilter) { - this.wrappedChannel = (OAuth2ClientChannel)wrappedChannel; - } - - public string ClientIdentifier { - get { return this.wrappedChannel.ClientIdentifier; } - set { this.wrappedChannel.ClientIdentifier = value; } - } - - public DotNetOpenAuth.OAuth2.ClientCredentialApplicator ClientCredentialApplicator { - get { return this.wrappedChannel.ClientCredentialApplicator; } - set { this.wrappedChannel.ClientCredentialApplicator = value; } - } - - public System.Xml.XmlDictionaryReaderQuotas JsonReaderQuotas { - get { return this.XmlDictionaryReaderQuotas; } - } - } -}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs deleted file mode 100644 index 9b552d3..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthConsumerChannel.cs +++ /dev/null @@ -1,155 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingOAuthConsumerChannel.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Threading; - using System.Web; - - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.OAuth.ChannelElements; - using DotNetOpenAuth.OAuth.Messages; - using Validation; - - /// <summary> - /// A special channel used in test simulations to pass messages directly between two parties. - /// </summary> - internal class CoordinatingOAuthConsumerChannel : OAuthConsumerChannel { - private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false); - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingOAuthConsumerChannel"/> class. - /// </summary> - /// <param name="signingBindingElement">The signing element for the Consumer to use. Null for the Service Provider.</param> - /// <param name="tokenManager">The token manager to use.</param> - /// <param name="securitySettings">The security settings.</param> - internal CoordinatingOAuthConsumerChannel(ITamperProtectionChannelBindingElement signingBindingElement, IConsumerTokenManager tokenManager, DotNetOpenAuth.OAuth.ConsumerSecuritySettings securitySettings) - : base( - signingBindingElement, - new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge), - tokenManager, - securitySettings) { - } - - internal EventWaitHandle IncomingMessageSignal { - get { return this.incomingMessageSignal; } - } - - internal IProtocolMessage IncomingMessage { get; set; } - - internal OutgoingWebResponse IncomingRawResponse { get; set; } - - /// <summary> - /// Gets or sets the coordinating channel used by the other party. - /// </summary> - internal CoordinatingOAuthServiceProviderChannel RemoteChannel { get; set; } - - internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request) { - ((ITamperResistantOAuthMessage)request).HttpMethod = this.GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods); - this.ProcessOutgoingMessage(request); - var requestInfo = this.SpoofHttpMethod(request); - TestBase.TestLogger.InfoFormat("Sending protected resource request: {0}", requestInfo.Message); - // Drop the outgoing message in the other channel's in-slot and let them know it's there. - this.RemoteChannel.IncomingMessage = requestInfo.Message; - this.RemoteChannel.IncomingMessageSignal.Set(); - return this.AwaitIncomingRawResponse(); - } - - protected internal override HttpRequestBase GetRequestFromContext() { - var directedMessage = (IDirectedProtocolMessage)this.AwaitIncomingMessage(); - return new CoordinatingHttpRequestInfo(directedMessage, directedMessage.HttpMethods); - } - - protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) { - var requestInfo = this.SpoofHttpMethod(request); - // Drop the outgoing message in the other channel's in-slot and let them know it's there. - this.RemoteChannel.IncomingMessage = requestInfo.Message; - this.RemoteChannel.IncomingMessageSignal.Set(); - // Now wait for a response... - return this.AwaitIncomingMessage(); - } - - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { - this.RemoteChannel.IncomingMessage = this.CloneSerializedParts(response); - this.RemoteChannel.IncomingMessageSignal.Set(); - return new OutgoingWebResponse(); // not used, but returning null is not allowed - } - - protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) { - // In this mock transport, direct and indirect messages are the same. - return this.PrepareDirectResponse(message); - } - - protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) { - var mockRequest = (CoordinatingHttpRequestInfo)request; - return mockRequest.Message; - } - - /// <summary> - /// Spoof HTTP request information for signing/verification purposes. - /// </summary> - /// <param name="message">The message to add a pretend HTTP method to.</param> - /// <returns>A spoofed HttpRequestInfo that wraps the new message.</returns> - private CoordinatingHttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) { - var signedMessage = message as ITamperResistantOAuthMessage; - if (signedMessage != null) { - string httpMethod = this.GetHttpMethod(signedMessage.HttpMethods); - signedMessage.HttpMethod = httpMethod; - } - - var requestInfo = new CoordinatingHttpRequestInfo(this.CloneSerializedParts(message), message.HttpMethods); - return requestInfo; - } - - private IProtocolMessage AwaitIncomingMessage() { - this.incomingMessageSignal.WaitOne(); - IProtocolMessage response = this.IncomingMessage; - this.IncomingMessage = null; - return response; - } - - private OutgoingWebResponse AwaitIncomingRawResponse() { - this.incomingMessageSignal.WaitOne(); - OutgoingWebResponse response = this.IncomingRawResponse; - this.IncomingRawResponse = null; - return response; - } - - private T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage { - Requires.NotNull(message, "message"); - - IProtocolMessage clonedMessage; - var messageAccessor = this.MessageDescriptions.GetAccessor(message); - var fields = messageAccessor.Serialize(); - - MessageReceivingEndpoint recipient = null; - var directedMessage = message as IDirectedProtocolMessage; - var directResponse = message as IDirectResponseProtocolMessage; - if (directedMessage != null && directedMessage.IsRequest()) { - if (directedMessage.Recipient != null) { - recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods); - } - - clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewRequestMessage(recipient, fields); - } else if (directResponse != null && directResponse.IsDirectResponse()) { - clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewResponseMessage(directResponse.OriginatingRequest, fields); - } else { - throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types."); - } - - // Fill the cloned message with data. - var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage); - clonedMessageAccessor.Deserialize(fields); - - return (T)clonedMessage; - } - - private string GetHttpMethod(HttpDeliveryMethods methods) { - return (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET"; - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs deleted file mode 100644 index a6f2a7f..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthServiceProviderChannel.cs +++ /dev/null @@ -1,163 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingOAuthServiceProviderChannel.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Threading; - using System.Web; - - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.Messaging.Bindings; - using DotNetOpenAuth.OAuth.ChannelElements; - using DotNetOpenAuth.OAuth.Messages; - using NUnit.Framework; - using Validation; - - /// <summary> - /// A special channel used in test simulations to pass messages directly between two parties. - /// </summary> - internal class CoordinatingOAuthServiceProviderChannel : OAuthServiceProviderChannel { - private EventWaitHandle incomingMessageSignal = new AutoResetEvent(false); - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingOAuthServiceProviderChannel"/> class. - /// </summary> - /// <param name="signingBindingElement">The signing element for the Consumer to use. Null for the Service Provider.</param> - /// <param name="tokenManager">The token manager to use.</param> - /// <param name="securitySettings">The security settings.</param> - internal CoordinatingOAuthServiceProviderChannel(ITamperProtectionChannelBindingElement signingBindingElement, IServiceProviderTokenManager tokenManager, DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings securitySettings) - : base( - signingBindingElement, - new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge), - tokenManager, - securitySettings, - new OAuthServiceProviderMessageFactory(tokenManager)) { - } - - internal EventWaitHandle IncomingMessageSignal { - get { return this.incomingMessageSignal; } - } - - internal IProtocolMessage IncomingMessage { get; set; } - - internal OutgoingWebResponse IncomingRawResponse { get; set; } - - /// <summary> - /// Gets or sets the coordinating channel used by the other party. - /// </summary> - internal CoordinatingOAuthConsumerChannel RemoteChannel { get; set; } - - internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request) { - ((ITamperResistantOAuthMessage)request).HttpMethod = GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods); - this.ProcessOutgoingMessage(request); - var requestInfo = this.SpoofHttpMethod(request); - TestBase.TestLogger.InfoFormat("Sending protected resource request: {0}", requestInfo.Message); - // Drop the outgoing message in the other channel's in-slot and let them know it's there. - this.RemoteChannel.IncomingMessage = requestInfo.Message; - this.RemoteChannel.IncomingMessageSignal.Set(); - return this.AwaitIncomingRawResponse(); - } - - internal void SendDirectRawResponse(OutgoingWebResponse response) { - this.RemoteChannel.IncomingRawResponse = response; - this.RemoteChannel.IncomingMessageSignal.Set(); - } - - protected internal override HttpRequestBase GetRequestFromContext() { - var directedMessage = (IDirectedProtocolMessage)this.AwaitIncomingMessage(); - return new CoordinatingHttpRequestInfo(directedMessage, directedMessage.HttpMethods); - } - - protected override IProtocolMessage RequestCore(IDirectedProtocolMessage request) { - var requestInfo = this.SpoofHttpMethod(request); - // Drop the outgoing message in the other channel's in-slot and let them know it's there. - this.RemoteChannel.IncomingMessage = requestInfo.Message; - this.RemoteChannel.IncomingMessageSignal.Set(); - // Now wait for a response... - return this.AwaitIncomingMessage(); - } - - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { - this.RemoteChannel.IncomingMessage = this.CloneSerializedParts(response); - this.RemoteChannel.IncomingMessageSignal.Set(); - return new OutgoingWebResponse(); // not used, but returning null is not allowed - } - - protected override OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) { - // In this mock transport, direct and indirect messages are the same. - return this.PrepareDirectResponse(message); - } - - protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request) { - var mockRequest = (CoordinatingHttpRequestInfo)request; - return mockRequest.Message; - } - - private static string GetHttpMethod(HttpDeliveryMethods methods) { - return (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET"; - } - - /// <summary> - /// Spoof HTTP request information for signing/verification purposes. - /// </summary> - /// <param name="message">The message to add a pretend HTTP method to.</param> - /// <returns>A spoofed HttpRequestInfo that wraps the new message.</returns> - private CoordinatingHttpRequestInfo SpoofHttpMethod(IDirectedProtocolMessage message) { - var signedMessage = message as ITamperResistantOAuthMessage; - if (signedMessage != null) { - string httpMethod = GetHttpMethod(signedMessage.HttpMethods); - signedMessage.HttpMethod = httpMethod; - } - - var requestInfo = new CoordinatingHttpRequestInfo(this.CloneSerializedParts(message), message.HttpMethods); - return requestInfo; - } - - private IProtocolMessage AwaitIncomingMessage() { - this.IncomingMessageSignal.WaitOne(); - Assert.That(this.IncomingMessage, Is.Not.Null, "Incoming message signaled, but none supplied."); - IProtocolMessage response = this.IncomingMessage; - this.IncomingMessage = null; - return response; - } - - private OutgoingWebResponse AwaitIncomingRawResponse() { - this.IncomingMessageSignal.WaitOne(); - OutgoingWebResponse response = this.IncomingRawResponse; - this.IncomingRawResponse = null; - return response; - } - - private T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage { - Requires.NotNull(message, "message"); - - IProtocolMessage clonedMessage; - var messageAccessor = this.MessageDescriptions.GetAccessor(message); - var fields = messageAccessor.Serialize(); - - MessageReceivingEndpoint recipient = null; - var directedMessage = message as IDirectedProtocolMessage; - var directResponse = message as IDirectResponseProtocolMessage; - if (directedMessage != null && directedMessage.IsRequest()) { - if (directedMessage.Recipient != null) { - recipient = new MessageReceivingEndpoint(directedMessage.Recipient, directedMessage.HttpMethods); - } - - clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewRequestMessage(recipient, fields); - } else if (directResponse != null && directResponse.IsDirectResponse()) { - clonedMessage = this.RemoteChannel.MessageFactoryTestHook.GetNewResponseMessage(directResponse.OriginatingRequest, fields); - } else { - throw new InvalidOperationException("Totally expected a message to implement one of the two derived interface types."); - } - - // Fill the cloned message with data. - var clonedMessageAccessor = this.MessageDescriptions.GetAccessor(clonedMessage); - clonedMessageAccessor.Deserialize(fields); - - return (T)clonedMessage; - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs deleted file mode 100644 index 9df791c..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs +++ /dev/null @@ -1,47 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="CoordinatingOutgoingWebResponse.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - using Validation; - - internal class CoordinatingOutgoingWebResponse : OutgoingWebResponse { - private CoordinatingChannel receivingChannel; - - private CoordinatingChannel sendingChannel; - - /// <summary> - /// Initializes a new instance of the <see cref="CoordinatingOutgoingWebResponse"/> class. - /// </summary> - /// <param name="message">The direct response message to send to the remote channel. This message will be cloned.</param> - /// <param name="receivingChannel">The receiving channel.</param> - /// <param name="sendingChannel">The sending channel.</param> - internal CoordinatingOutgoingWebResponse(IProtocolMessage message, CoordinatingChannel receivingChannel, CoordinatingChannel sendingChannel) { - Requires.NotNull(message, "message"); - Requires.NotNull(receivingChannel, "receivingChannel"); - Requires.NotNull(sendingChannel, "sendingChannel"); - - this.receivingChannel = receivingChannel; - this.sendingChannel = sendingChannel; - this.OriginalMessage = message; - } - - [EditorBrowsable(EditorBrowsableState.Never)] - public override void Send() { - this.Respond(); - } - - public override void Respond() { - this.sendingChannel.SaveCookies(this.Cookies); - this.receivingChannel.PostMessage(this.OriginalMessage); - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs index 494a1c1..7fac125 100644 --- a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs +++ b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs @@ -14,7 +14,7 @@ namespace DotNetOpenAuth.Test.Mocks { using DotNetOpenAuth.OAuth.Messages; using DotNetOpenAuth.Test.OAuth; - internal class InMemoryTokenManager : IConsumerTokenManager, IServiceProviderTokenManager { + internal class InMemoryTokenManager : IServiceProviderTokenManager { private KeyedCollectionDelegate<string, ConsumerInfo> consumers = new KeyedCollectionDelegate<string, ConsumerInfo>(c => c.Key); private KeyedCollectionDelegate<string, TokenInfo> tokens = new KeyedCollectionDelegate<string, TokenInfo>(t => t.Token); @@ -28,18 +28,6 @@ namespace DotNetOpenAuth.Test.Mocks { /// </summary> private List<string> accessTokens = new List<string>(); - #region IConsumerTokenManager Members - - public string ConsumerKey { - get { return this.consumers.Single().Key; } - } - - public string ConsumerSecret { - get { return this.consumers.Single().Secret; } - } - - #endregion - #region ITokenManager Members public string GetTokenSecret(string token) { diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs index d20671e..349be56 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs @@ -10,7 +10,9 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Globalization; using System.IO; using System.Net; + using System.Net.Http; using System.Text; + using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; @@ -19,71 +21,8 @@ namespace DotNetOpenAuth.Test.Mocks { using DotNetOpenAuth.Yadis; using Validation; - internal class MockHttpRequest { - private readonly Dictionary<Uri, IncomingWebResponse> registeredMockResponses = new Dictionary<Uri, IncomingWebResponse>(); - - private MockHttpRequest(IDirectWebRequestHandler mockHandler) { - Requires.NotNull(mockHandler, "mockHandler"); - this.MockWebRequestHandler = mockHandler; - } - - internal IDirectWebRequestHandler MockWebRequestHandler { get; private set; } - - internal static MockHttpRequest CreateUntrustedMockHttpHandler() { - TestWebRequestHandler testHandler = new TestWebRequestHandler(); - UntrustedWebRequestHandler untrustedHandler = new UntrustedWebRequestHandler(testHandler); - if (!untrustedHandler.WhitelistHosts.Contains("localhost")) { - untrustedHandler.WhitelistHosts.Add("localhost"); - } - untrustedHandler.WhitelistHosts.Add(OpenIdTestBase.OPUri.Host); - MockHttpRequest mock = new MockHttpRequest(untrustedHandler); - testHandler.Callback = mock.GetMockResponse; - return mock; - } - - internal void RegisterMockResponse(IncomingWebResponse response) { - Requires.NotNull(response, "response"); - if (this.registeredMockResponses.ContainsKey(response.RequestUri)) { - Logger.Http.WarnFormat("Mock HTTP response already registered for {0}.", response.RequestUri); - } else { - this.registeredMockResponses.Add(response.RequestUri, response); - } - } - - internal void RegisterMockResponse(Uri requestUri, string contentType, string responseBody) { - this.RegisterMockResponse(requestUri, requestUri, contentType, responseBody); - } - - internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, string responseBody) { - this.RegisterMockResponse(requestUri, responseUri, contentType, new WebHeaderCollection(), responseBody); - } - - internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string responseBody) { - Requires.NotNull(requestUri, "requestUri"); - Requires.NotNull(responseUri, "responseUri"); - Requires.NotNullOrEmpty(contentType, "contentType"); - - // Set up the redirect if appropriate - if (requestUri != responseUri) { - this.RegisterMockRedirect(requestUri, responseUri); - } - - string contentEncoding = null; - MemoryStream stream = new MemoryStream(); - StreamWriter sw = new StreamWriter(stream); - sw.Write(responseBody); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - this.RegisterMockResponse(new CachedDirectWebResponse(responseUri, responseUri, headers ?? new WebHeaderCollection(), HttpStatusCode.OK, contentType, contentEncoding, stream)); - } - - internal void RegisterMockXrdsResponses(IDictionary<string, string> requestUriAndResponseBody) { - foreach (var pair in requestUriAndResponseBody) { - this.RegisterMockResponse(new Uri(pair.Key), "text/xml; saml=false; https=false; charset=UTF-8", pair.Value); - } - } - - internal void RegisterMockXrdsResponse(IdentifierDiscoveryResult endpoint) { + internal static class MockHttpRequest { + internal static void RegisterMockXrdsResponse(this TestBase test, IdentifierDiscoveryResult endpoint) { Requires.NotNull(endpoint, "endpoint"); string identityUri; @@ -92,13 +31,14 @@ namespace DotNetOpenAuth.Test.Mocks { } else { identityUri = endpoint.UserSuppliedIdentifier ?? endpoint.ClaimedIdentifier; } - this.RegisterMockXrdsResponse(new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint }); + + RegisterMockXrdsResponse(test, new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint }); } - internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<IdentifierDiscoveryResult> endpoints) { + internal static void RegisterMockXrdsResponse(this TestBase test, Uri respondingUri, IEnumerable<IdentifierDiscoveryResult> endpoints) { Requires.NotNull(endpoints, "endpoints"); - StringBuilder xrds = new StringBuilder(); + var xrds = new StringBuilder(); xrds.AppendLine(@"<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns:openid='http://openid.net/xmlns/1.0' xmlns='xri://$xrd*($v*2.0)'> <XRD>"); foreach (var endpoint in endpoints) { @@ -127,10 +67,10 @@ namespace DotNetOpenAuth.Test.Mocks { </XRD> </xrds:XRDS>"); - this.RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); + test.Handle(respondingUri).By(xrds.ToString(), ContentTypes.Xrds); } - internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { + internal static void RegisterMockXrdsResponse(this TestBase test, UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { IdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, directedIdentityAssignedIdentifier, @@ -138,16 +78,16 @@ namespace DotNetOpenAuth.Test.Mocks { new ProviderEndpointDescription(providerEndpoint.ProviderEndpoint, providerEndpoint.Capabilities), 10, 10); - this.RegisterMockXrdsResponse(identityEndpoint); + RegisterMockXrdsResponse(test, identityEndpoint); } - internal Identifier RegisterMockXrdsResponse(string embeddedResourcePath) { - UriIdentifier id = new Uri(new Uri("http://localhost/"), embeddedResourcePath); - this.RegisterMockResponse(id, "application/xrds+xml", OpenIdTestBase.LoadEmbeddedFile(embeddedResourcePath)); - return id; + internal static void RegisterMockXrdsResponse(this TestBase test, string embeddedResourcePath, out Identifier id) { + id = new Uri(new Uri("http://localhost/"), embeddedResourcePath); + test.Handle(new Uri(id)) + .By(OpenIdTestBase.LoadEmbeddedFile(embeddedResourcePath), "application/xrds+xml"); } - internal void RegisterMockRPDiscovery() { + internal static void RegisterMockRPDiscovery(this TestBase test, bool ssl) { string template = @"<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns:openid='http://openid.net/xmlns/1.0' xmlns='xri://$xrd*($v*2.0)'> <XRD> <Service priority='10'> @@ -164,44 +104,62 @@ namespace DotNetOpenAuth.Test.Mocks { HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUri.AbsoluteUri), HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUriSsl.AbsoluteUri)); - this.RegisterMockResponse(OpenIdTestBase.RPRealmUri, ContentTypes.Xrds, xrds); - this.RegisterMockResponse(OpenIdTestBase.RPRealmUriSsl, ContentTypes.Xrds, xrds); + test.Handle(ssl ? OpenIdTestBase.RPRealmUriSsl : OpenIdTestBase.RPRealmUri) + .By(xrds, ContentTypes.Xrds); } - internal void DeleteResponse(Uri requestUri) { - this.registeredMockResponses.Remove(requestUri); + internal static void RegisterMockRedirect(this TestBase test, Uri origin, Uri redirectLocation) { + var response = new HttpResponseMessage(HttpStatusCode.Redirect); + response.Headers.Location = redirectLocation; + test.Handle(origin).By(req => response); } - internal void RegisterMockRedirect(Uri origin, Uri redirectLocation) { - var redirectionHeaders = new WebHeaderCollection { - { HttpResponseHeader.Location, redirectLocation.AbsoluteUri }, - }; - IncomingWebResponse response = new CachedDirectWebResponse(origin, origin, redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream()); - this.RegisterMockResponse(response); + internal static void RegisterMockXrdsResponses(this TestBase test, IEnumerable<KeyValuePair<string, string>> urlXrdsPairs) { + Requires.NotNull(urlXrdsPairs, "urlXrdsPairs"); + + foreach (var keyValuePair in urlXrdsPairs) { + test.Handle(new Uri(keyValuePair.Key)).By(keyValuePair.Value, ContentTypes.Xrds); + } } - internal void RegisterMockNotFound(Uri requestUri) { - CachedDirectWebResponse errorResponse = new CachedDirectWebResponse( - requestUri, - requestUri, - new WebHeaderCollection(), - HttpStatusCode.NotFound, - "text/plain", - Encoding.UTF8.WebName, - new MemoryStream(Encoding.UTF8.GetBytes("Not found."))); - this.RegisterMockResponse(errorResponse); + internal static void RegisterMockResponse(this TestBase test, Uri url, string contentType, string content) { + test.Handle(url).By(content, contentType); } - private IncomingWebResponse GetMockResponse(HttpWebRequest request) { - IncomingWebResponse response; - if (this.registeredMockResponses.TryGetValue(request.RequestUri, out response)) { - // reset response stream position so this response can be reused on a subsequent request. - response.ResponseStream.Seek(0, SeekOrigin.Begin); + internal static void RegisterMockResponse(this TestBase test, Uri requestUri, Uri responseUri, string contentType, string content) { + RegisterMockResponse(test, requestUri, responseUri, contentType, null, content); + } + + internal static void RegisterMockResponse(this TestBase test, Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string content) { + Requires.NotNull(requestUri, "requestUri"); + Requires.NotNull(responseUri, "responseUri"); + Requires.NotNullOrEmpty(contentType, "contentType"); + + test.Handle(requestUri).By(req => { + var response = new HttpResponseMessage(); + response.RequestMessage = req; + + if (requestUri != responseUri) { + // Simulate having followed redirects to get the final response. + var clonedRequest = MessagingUtilities.Clone(req); + clonedRequest.RequestUri = responseUri; + response.RequestMessage = clonedRequest; + } + + response.CopyHeadersFrom(headers); + response.Content = new StringContent(content, Encoding.Default, contentType); return response; - } else { - ////Assert.Fail("Unexpected HTTP request: {0}", uri); - Logger.Http.WarnFormat("Unexpected HTTP request: {0}", request.RequestUri); - return new CachedDirectWebResponse(request.RequestUri, request.RequestUri, new WebHeaderCollection(), HttpStatusCode.NotFound, "text/html", null, new MemoryStream()); + }); + } + + private static void CopyHeadersFrom(this HttpResponseMessage message, WebHeaderCollection headers) { + if (headers != null) { + foreach (string headerName in headers) { + string[] headerValues = headers.GetValues(headerName); + if (!message.Headers.TryAddWithoutValidation(headerName, headerValues)) { + message.Content.Headers.TryAddWithoutValidation(headerName, headerValues); + } + } } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs deleted file mode 100644 index f020923..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="MockIdentifier.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - using Validation; - - /// <summary> - /// Performs similar to an ordinary <see cref="Identifier"/>, but when called upon - /// to perform discovery, it returns a preset list of sevice endpoints to avoid - /// having a dependency on a hosted web site to actually perform discovery on. - /// </summary> - internal class MockIdentifier : Identifier { - private IEnumerable<IdentifierDiscoveryResult> endpoints; - - private MockHttpRequest mockHttpRequest; - - private Identifier wrappedIdentifier; - - public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<IdentifierDiscoveryResult> endpoints) - : base(wrappedIdentifier.OriginalString, false) { - Requires.NotNull(wrappedIdentifier, "wrappedIdentifier"); - Requires.NotNull(mockHttpRequest, "mockHttpRequest"); - Requires.NotNull(endpoints, "endpoints"); - - this.wrappedIdentifier = wrappedIdentifier; - this.endpoints = endpoints; - this.mockHttpRequest = mockHttpRequest; - - // Register a mock HTTP response to enable discovery of this identifier within the RP - // without having to host an ASP.NET site within the test. - mockHttpRequest.RegisterMockXrdsResponse(new Uri(wrappedIdentifier.ToString()), endpoints); - } - - internal IEnumerable<IdentifierDiscoveryResult> DiscoveryEndpoints { - get { return this.endpoints; } - } - - public override string ToString() { - return this.wrappedIdentifier.ToString(); - } - - public override bool Equals(object obj) { - return this.wrappedIdentifier.Equals(obj); - } - - public override int GetHashCode() { - return this.wrappedIdentifier.GetHashCode(); - } - - internal override Identifier TrimFragment() { - return this; - } - - internal override bool TryRequireSsl(out Identifier secureIdentifier) { - // We take special care to make our wrapped identifier secure, but still - // return a mocked (secure) identifier. - Identifier secureWrappedIdentifier; - bool result = this.wrappedIdentifier.TryRequireSsl(out secureWrappedIdentifier); - secureIdentifier = new MockIdentifier(secureWrappedIdentifier, this.mockHttpRequest, this.endpoints); - return result; - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs deleted file mode 100644 index 0118851..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs +++ /dev/null @@ -1,47 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="MockIdentifierDiscoveryService.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - - internal class MockIdentifierDiscoveryService : IIdentifierDiscoveryService { - /// <summary> - /// Initializes a new instance of the <see cref="MockIdentifierDiscoveryService"/> class. - /// </summary> - public MockIdentifierDiscoveryService() { - } - - #region IIdentifierDiscoveryService Members - - /// <summary> - /// 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> - /// <returns> - /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. - /// </returns> - public IEnumerable<IdentifierDiscoveryResult> Discover(Identifier identifier, IDirectWebRequestHandler requestHandler, out bool abortDiscoveryChain) { - var mockIdentifier = identifier as MockIdentifier; - if (mockIdentifier == null) { - abortDiscoveryChain = false; - return Enumerable.Empty<IdentifierDiscoveryResult>(); - } - - abortDiscoveryChain = true; - return mockIdentifier.DiscoveryEndpoints; - } - - #endregion - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs index 8509c03..38f9daf 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs @@ -7,6 +7,9 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using Validation; @@ -30,15 +33,16 @@ namespace DotNetOpenAuth.Test.Mocks { /// Searches for an XRDS document at the realm URL, and if found, searches /// for a description of a relying party endpoints (OpenId login pages). /// </summary> - /// <param name="requestHandler">The mechanism to use for sending HTTP requests.</param> + /// <param name="hostFactories">The host factories.</param> /// <param name="allowRedirects">Whether redirects may be followed when discovering the Realm. /// This may be true when creating an unsolicited assertion, but must be /// false when performing return URL verification per 2.0 spec section 9.2.1.</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The details of the endpoints if found, otherwise null. /// </returns> - internal override IEnumerable<RelyingPartyEndpointDescription> DiscoverReturnToEndpoints(IDirectWebRequestHandler requestHandler, bool allowRedirects) { - return this.relyingPartyDescriptions; + internal override Task<IEnumerable<RelyingPartyEndpointDescription>> DiscoverReturnToEndpointsAsync(IHostFactories hostFactories, bool allowRedirects, CancellationToken cancellationToken) { + return Task.FromResult<IEnumerable<RelyingPartyEndpointDescription>>(this.relyingPartyDescriptions); } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs index 1733f17..58a2367 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockReplayProtectionBindingElement.cs @@ -5,6 +5,9 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.Test.Mocks { + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using NUnit.Framework; @@ -23,17 +26,17 @@ namespace DotNetOpenAuth.Test.Mocks { /// </summary> public Channel Channel { get; set; } - MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) { + Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var replayMessage = message as IReplayProtectedProtocolMessage; if (replayMessage != null) { replayMessage.Nonce = "someNonce"; - return MessageProtections.ReplayProtection; + return MessageProtectionTasks.ReplayProtection; } - return null; + return MessageProtectionTasks.Null; } - MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) { + Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var replayMessage = message as IReplayProtectedProtocolMessage; if (replayMessage != null) { Assert.AreEqual("someNonce", replayMessage.Nonce, "The nonce didn't serialize correctly, or something"); @@ -42,10 +45,10 @@ namespace DotNetOpenAuth.Test.Mocks { throw new ReplayedMessageException(message); } this.messageReceived = true; - return MessageProtections.ReplayProtection; + return MessageProtectionTasks.ReplayProtection; } - return null; + return MessageProtectionTasks.Null; } #endregion diff --git a/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs index aa68b0b..f0b2bfc 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockSigningBindingElement.cs @@ -9,6 +9,9 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Collections.Generic; using System.Linq; using System.Text; + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; @@ -26,26 +29,26 @@ namespace DotNetOpenAuth.Test.Mocks { /// </summary> public Channel Channel { get; set; } - MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) { - ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage; + Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { + var signedMessage = message as ITamperResistantProtocolMessage; if (signedMessage != null) { signedMessage.Signature = MessageSignature; - return MessageProtections.TamperProtection; + return MessageProtectionTasks.TamperProtection; } - return null; + return MessageProtectionTasks.Null; } - MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) { - ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage; + Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { + var signedMessage = message as ITamperResistantProtocolMessage; if (signedMessage != null) { if (signedMessage.Signature != MessageSignature) { throw new InvalidSignatureException(message); } - return MessageProtections.TamperProtection; + return MessageProtectionTasks.TamperProtection; } - return null; + return MessageProtectionTasks.Null; } #endregion diff --git a/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs b/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs index 2b3249f..35d7f1b 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockTransformationBindingElement.cs @@ -9,11 +9,14 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Collections.Generic; using System.Linq; using System.Text; + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using NUnit.Framework; internal class MockTransformationBindingElement : IChannelBindingElement { - private string transform; + private readonly string transform; internal MockTransformationBindingElement(string transform) { if (transform == null) { @@ -34,25 +37,25 @@ namespace DotNetOpenAuth.Test.Mocks { /// </summary> public Channel Channel { get; set; } - MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) { + Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var testMessage = message as TestMessage; if (testMessage != null) { testMessage.Name = this.transform + testMessage.Name; - return MessageProtections.None; + return MessageProtectionTasks.None; } - return null; + return MessageProtectionTasks.Null; } - MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) { + Task<MessageProtections?> IChannelBindingElement.ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) { var testMessage = message as TestMessage; if (testMessage != null) { StringAssert.StartsWith(this.transform, testMessage.Name); testMessage.Name = testMessage.Name.Substring(this.transform.Length); - return MessageProtections.None; + return MessageProtectionTasks.None; } - return null; + return MessageProtectionTasks.Null; } #endregion diff --git a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs index 263f0fd..344598f 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs @@ -7,15 +7,32 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; /// <summary> /// A Channel derived type that passes null to the protected constructor. /// </summary> internal class TestBadChannel : Channel { - internal TestBadChannel(bool badConstructorParam) - : base(badConstructorParam ? null : new TestMessageFactory()) { + /// <summary> + /// Initializes a new instance of the <see cref="TestBadChannel" /> class. + /// </summary> + /// <param name="messageFactory">The message factory. Could be <see cref="TestMessageFactory"/></param> + /// <param name="bindingElements">The binding elements.</param> + /// <param name="hostFactories">The host factories.</param> + internal TestBadChannel(IMessageFactory messageFactory, IChannelBindingElement[] bindingElements, IHostFactories hostFactories) + : base(messageFactory, bindingElements, hostFactories) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="TestBadChannel"/> class. + /// </summary> + internal TestBadChannel() + : this(new TestMessageFactory(), new IChannelBindingElement[0], new DefaultOpenIdHostFactories()) { } internal new void Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields, bool payloadInFragment = false) { @@ -34,15 +51,15 @@ namespace DotNetOpenAuth.Test.Mocks { return base.Receive(fields, recipient); } - internal new IProtocolMessage ReadFromRequest(HttpRequestBase request) { - return base.ReadFromRequest(request); + internal new Task<IDirectedProtocolMessage> ReadFromRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) { + return base.ReadFromRequestAsync(request, cancellationToken); } - protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) { + protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) { throw new NotImplementedException(); } - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { + protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) { throw new NotImplementedException(); } } diff --git a/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs b/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs index 1472231..5b318d5 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs @@ -8,21 +8,26 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId; internal class TestChannel : Channel { - internal TestChannel() - : this(new TestMessageFactory()) { + internal TestChannel(IHostFactories hostFactories = null) + : this(new TestMessageFactory(), new IChannelBindingElement[0], hostFactories ?? new DefaultOpenIdHostFactories()) { } - internal TestChannel(MessageDescriptionCollection messageDescriptions) - : this() { + internal TestChannel(MessageDescriptionCollection messageDescriptions, IHostFactories hostFactories = null) + : this(hostFactories) { this.MessageDescriptions = messageDescriptions; } - internal TestChannel(IMessageFactory messageTypeProvider, params IChannelBindingElement[] bindingElements) - : base(messageTypeProvider, bindingElements) { + internal TestChannel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements, IHostFactories hostFactories) + : base(messageTypeProvider, bindingElements, hostFactories) { } /// <summary> @@ -40,15 +45,15 @@ namespace DotNetOpenAuth.Test.Mocks { return base.Receive(fields, recipient); } - protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) { + protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) { throw new NotImplementedException("ReadFromResponseInternal"); } - protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) { + protected override HttpRequestMessage CreateHttpRequest(IDirectedProtocolMessage request) { throw new NotImplementedException("CreateHttpRequest"); } - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { + protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) { throw new NotImplementedException("SendDirectMessageResponse"); } } diff --git a/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs b/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs deleted file mode 100644 index b38a3d8..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs +++ /dev/null @@ -1,116 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="TestWebRequestHandler.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.IO; - using System.Net; - using System.Text; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OAuth.ChannelElements; - - internal class TestWebRequestHandler : IDirectWebRequestHandler { - private Stream postEntity; - - /// <summary> - /// Gets or sets the callback used to provide the mock response for the mock request. - /// </summary> - internal Func<HttpWebRequest, IncomingWebResponse> Callback { get; set; } - - /// <summary> - /// Gets the stream that was written out as if on an HTTP request. - /// </summary> - internal Stream RequestEntityStream { - get { - if (this.postEntity == null) { - return null; - } - - Stream result = new MemoryStream(); - long originalPosition = this.postEntity.Position; - this.postEntity.Position = 0; - this.postEntity.CopyTo(result); - this.postEntity.Position = originalPosition; - result.Position = 0; - return result; - } - } - - /// <summary> - /// Gets the stream that was written out as if on an HTTP request as an ordinary string. - /// </summary> - internal string RequestEntityAsString { - get { - if (this.postEntity == null) { - return null; - } - - StreamReader reader = new StreamReader(this.RequestEntityStream); - return reader.ReadToEnd(); - } - } - - #region IWebRequestHandler Members - - public bool CanSupport(DirectWebRequestOptions options) { - return true; - } - - /// <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 writer the caller should write out the entity data to. - /// </returns> - public Stream GetRequestStream(HttpWebRequest request) { - return this.GetRequestStream(request, DirectWebRequestOptions.None); - } - - public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) { - this.postEntity = new MemoryStream(); - return this.postEntity; - } - - /// <summary> - /// Processes an <see cref="HttpWebRequest"/> and converts the - /// <see cref="HttpWebResponse"/> to a <see cref="Response"/> instance. - /// </summary> - /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param> - /// <returns> - /// An instance of <see cref="Response"/> describing the response. - /// </returns> - public IncomingWebResponse GetResponse(HttpWebRequest request) { - return this.GetResponse(request, DirectWebRequestOptions.None); - } - - public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { - if (this.Callback == null) { - throw new InvalidOperationException("Set the Callback property first."); - } - - return this.Callback(request); - } - - #endregion - - #region IDirectSslWebRequestHandler Members - - public Stream GetRequestStream(HttpWebRequest request, bool requireSsl) { - ErrorUtilities.VerifyProtocol(!requireSsl || request.RequestUri.Scheme == Uri.UriSchemeHttps, "disallowed request"); - return this.GetRequestStream(request); - } - - public IncomingWebResponse GetResponse(HttpWebRequest request, bool requireSsl) { - ErrorUtilities.VerifyProtocol(!requireSsl || request.RequestUri.Scheme == Uri.UriSchemeHttps, "disallowed request"); - var result = this.GetResponse(request); - ErrorUtilities.VerifyProtocol(!requireSsl || result.FinalUri.Scheme == Uri.UriSchemeHttps, "disallowed request"); - return result; - } - - #endregion - } -} |