summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-09-29 23:16:41 -0700
committerAndrew <andrewarnott@gmail.com>2008-10-02 07:33:55 -0700
commit5cbd5d7edb994f874b265ed2e7c43f0bcd27b6ac (patch)
treea7b11de02bc213b279906aaa4aafc7d15ff09bac
parent55c86fc27084af191bbb80fb91da34c24b945c3e (diff)
downloadDotNetOpenAuth-5cbd5d7edb994f874b265ed2e7c43f0bcd27b6ac.zip
DotNetOpenAuth-5cbd5d7edb994f874b265ed2e7c43f0bcd27b6ac.tar.gz
DotNetOpenAuth-5cbd5d7edb994f874b265ed2e7c43f0bcd27b6ac.tar.bz2
Removed the queue/dequeue methodology of queued responses. Now the methods that generate them return them.
Besides simplifying the API somewhat, this change allows for Consumer, ServiceProvider and Channel classes to be entirely threadsafe and reusable.
-rw-r--r--src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs3
-rw-r--r--src/DotNetOAuth.Test/Messaging/ChannelTests.cs25
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestBadChannel.cs6
-rw-r--r--src/DotNetOAuth.Test/Mocks/TestChannel.cs2
-rw-r--r--src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs7
-rw-r--r--src/DotNetOAuth/ChannelElements/OAuthChannel.cs5
-rw-r--r--src/DotNetOAuth/Consumer.cs11
-rw-r--r--src/DotNetOAuth/Messaging/Channel.cs48
-rw-r--r--src/DotNetOAuth/ServiceProvider.cs15
9 files changed, 31 insertions, 91 deletions
diff --git a/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs b/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
index 38ca5f1..790a0d4 100644
--- a/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
+++ b/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
@@ -78,9 +78,8 @@ namespace DotNetOAuth.Test.ChannelElements {
Name = "Andrew",
Location = new Uri("http://hostb/pathB"),
};
- this.channel.Send(message);
- Response response = this.channel.DequeueIndirectOrResponseMessage();
+ Response response = this.channel.Send(message);
Assert.AreSame(message, response.OriginalMessage);
Assert.AreEqual(HttpStatusCode.OK, response.Status);
Assert.AreEqual(0, response.Headers.Count);
diff --git a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
index e9dd6ea..9caa10d 100644
--- a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
@@ -25,11 +25,6 @@ namespace DotNetOAuth.Test.Messaging {
}
[TestMethod]
- public void DequeueIndirectOrResponseMessageReturnsNull() {
- Assert.IsNull(this.Channel.DequeueIndirectOrResponseMessage());
- }
-
- [TestMethod]
public void ReadFromRequestQueryString() {
this.ParameterizedReceiveTest("GET");
}
@@ -69,8 +64,7 @@ namespace DotNetOAuth.Test.Messaging {
message.Recipient = new Uri("http://provider/path");
var expected = GetStandardTestFields(FieldFill.CompleteBeforeBindings);
- this.Channel.Send(message);
- Response response = this.Channel.DequeueIndirectOrResponseMessage();
+ Response response = this.Channel.Send(message);
Assert.AreEqual(HttpStatusCode.Redirect, response.Status);
StringAssert.StartsWith(response.Headers[HttpResponseHeader.Location], "http://provider/path");
foreach (var pair in expected) {
@@ -113,8 +107,7 @@ namespace DotNetOAuth.Test.Messaging {
Location = new Uri("http://host/path"),
Recipient = new Uri("http://provider/path"),
};
- this.Channel.Send(message);
- Response response = this.Channel.DequeueIndirectOrResponseMessage();
+ Response response = this.Channel.Send(message);
Assert.AreEqual(HttpStatusCode.OK, response.Status, "A form redirect should be an HTTP successful response.");
Assert.IsNull(response.Headers[HttpResponseHeader.Location], "There should not be a redirection header in the response.");
string body = response.Body;
@@ -166,20 +159,6 @@ namespace DotNetOAuth.Test.Messaging {
}
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
- public void QueueIndirectOrResponseMessageNull() {
- TestBadChannel badChannel = new TestBadChannel(false);
- badChannel.QueueIndirectOrResponseMessage(null);
- }
-
- [TestMethod, ExpectedException(typeof(InvalidOperationException))]
- public void QueueIndirectOrResponseMessageTwice() {
- TestBadChannel badChannel = new TestBadChannel(false);
- Response response = new Response();
- badChannel.QueueIndirectOrResponseMessage(new Response());
- badChannel.QueueIndirectOrResponseMessage(new Response());
- }
-
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void SendIndirectMessageNull() {
TestBadChannel badChannel = new TestBadChannel(false);
badChannel.SendIndirectMessage(null);
diff --git a/src/DotNetOAuth.Test/Mocks/TestBadChannel.cs b/src/DotNetOAuth.Test/Mocks/TestBadChannel.cs
index 5b59ba1..781d65b 100644
--- a/src/DotNetOAuth.Test/Mocks/TestBadChannel.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestBadChannel.cs
@@ -27,10 +27,6 @@ namespace DotNetOAuth.Test.Mocks {
base.CreateFormPostResponse(message, fields);
}
- internal new void QueueIndirectOrResponseMessage(Response response) {
- base.QueueIndirectOrResponseMessage(response);
- }
-
internal new void SendIndirectMessage(IDirectedProtocolMessage message) {
base.SendIndirectMessage(message);
}
@@ -51,7 +47,7 @@ namespace DotNetOAuth.Test.Mocks {
throw new NotImplementedException();
}
- protected override void SendDirectMessageResponse(IProtocolMessage response) {
+ protected override Response SendDirectMessageResponse(IProtocolMessage response) {
throw new NotImplementedException();
}
}
diff --git a/src/DotNetOAuth.Test/Mocks/TestChannel.cs b/src/DotNetOAuth.Test/Mocks/TestChannel.cs
index b69b756..1f75e3f 100644
--- a/src/DotNetOAuth.Test/Mocks/TestChannel.cs
+++ b/src/DotNetOAuth.Test/Mocks/TestChannel.cs
@@ -28,7 +28,7 @@ namespace DotNetOAuth.Test.Mocks {
throw new NotImplementedException("ReadFromResponse");
}
- protected override void SendDirectMessageResponse(IProtocolMessage response) {
+ protected override Response SendDirectMessageResponse(IProtocolMessage response) {
throw new NotImplementedException("SendDirectMessageResponse");
}
}
diff --git a/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs b/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
index 67f5ad6..5b74342 100644
--- a/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
+++ b/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
@@ -68,17 +68,18 @@ namespace DotNetOAuth.Test.Scenarios {
return this.AwaitIncomingMessage();
}
- protected override void SendDirectMessageResponse(IProtocolMessage response) {
+ protected override Response SendDirectMessageResponse(IProtocolMessage response) {
TestBase.TestLogger.InfoFormat("Sending response: {0}", response);
this.RemoteChannel.incomingMessage = CloneSerializedParts(response, null);
this.CopyDirectionalParts(response, this.RemoteChannel.incomingMessage);
this.RemoteChannel.incomingMessageSignal.Set();
+ return null;
}
- protected override void SendIndirectMessage(IDirectedProtocolMessage message) {
+ protected override Response SendIndirectMessage(IDirectedProtocolMessage message) {
TestBase.TestLogger.Info("Next response is an indirect message...");
// In this mock transport, direct and indirect messages are the same.
- this.SendDirectMessageResponse(message);
+ return this.SendDirectMessageResponse(message);
}
protected override HttpRequestInfo GetRequestFromContext() {
diff --git a/src/DotNetOAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
index 03db91e..951df05 100644
--- a/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
@@ -208,10 +208,11 @@ namespace DotNetOAuth.ChannelElements {
/// are sent in the response stream in querystring style.
/// </summary>
/// <param name="response">The message to send as a response.</param>
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
/// <remarks>
/// This method implements spec V1.0 section 5.3.
/// </remarks>
- protected override void SendDirectMessageResponse(IProtocolMessage response) {
+ protected override Response SendDirectMessageResponse(IProtocolMessage response) {
MessageSerializer serializer = MessageSerializer.Get(response.GetType());
var fields = serializer.Serialize(response);
string responseBody = MessagingUtilities.CreateQueryString(fields);
@@ -222,7 +223,7 @@ namespace DotNetOAuth.ChannelElements {
Status = HttpStatusCode.OK,
Headers = new System.Net.WebHeaderCollection(),
};
- this.QueueIndirectOrResponseMessage(encodedResponse);
+ return encodedResponse;
}
/// <summary>
diff --git a/src/DotNetOAuth/Consumer.cs b/src/DotNetOAuth/Consumer.cs
index ce61e60..bc50d1f 100644
--- a/src/DotNetOAuth/Consumer.cs
+++ b/src/DotNetOAuth/Consumer.cs
@@ -59,11 +59,6 @@ namespace DotNetOAuth {
public ITokenManager TokenManager { get; private set; }
/// <summary>
- /// Gets the pending user agent redirect based message to be sent as an HttpResponse.
- /// </summary>
- public Response PendingRequest { get; private set; }
-
- /// <summary>
/// Gets or sets the object that processes <see cref="HttpWebRequest"/>s.
/// </summary>
/// <remarks>
@@ -86,7 +81,8 @@ namespace DotNetOAuth {
/// User Agent to upon successful authorization.
/// </param>
/// <param name="extraParameters">Extra parameters to add to the request token message. Optional.</param>
- public void RequestUserAuthorization(Uri callback, IDictionary<string, string> extraParameters) {
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
+ public Response RequestUserAuthorization(Uri callback, IDictionary<string, string> extraParameters) {
// Obtain an unauthorized request token.
var requestToken = new RequestTokenMessage(this.ServiceProvider.RequestTokenEndpoint) {
ConsumerKey = this.ConsumerKey,
@@ -101,8 +97,7 @@ namespace DotNetOAuth {
Callback = callback,
RequestToken = requestTokenResponse.RequestToken,
};
- this.Channel.Send(requestAuthorization);
- this.PendingRequest = this.Channel.DequeueIndirectOrResponseMessage();
+ return this.Channel.Send(requestAuthorization);
}
/// <summary>
diff --git a/src/DotNetOAuth/Messaging/Channel.cs b/src/DotNetOAuth/Messaging/Channel.cs
index d16cdc3..e3e49d8 100644
--- a/src/DotNetOAuth/Messaging/Channel.cs
+++ b/src/DotNetOAuth/Messaging/Channel.cs
@@ -55,11 +55,6 @@ namespace DotNetOAuth.Messaging {
private IMessageTypeProvider messageTypeProvider;
/// <summary>
- /// Gets or sets the HTTP response to send as a reply to the current incoming HTTP request.
- /// </summary>
- private Response queuedIndirectOrResponseMessage;
-
- /// <summary>
/// A list of binding elements in the order they must be applied to outgoing messages.
/// </summary>
/// <remarks>
@@ -106,21 +101,12 @@ namespace DotNetOAuth.Messaging {
}
/// <summary>
- /// Retrieves the stored response for sending and clears it from the channel.
- /// </summary>
- /// <returns>The response to send as the HTTP response.</returns>
- internal Response DequeueIndirectOrResponseMessage() {
- Response response = this.queuedIndirectOrResponseMessage;
- this.queuedIndirectOrResponseMessage = null;
- return response;
- }
-
- /// <summary>
/// Queues an indirect message (either a request or response)
/// or direct message response for transmission to a remote party.
/// </summary>
/// <param name="message">The one-way message to send</param>
- internal void Send(IProtocolMessage message) {
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
+ internal Response Send(IProtocolMessage message) {
if (message == null) {
throw new ArgumentNullException("message");
}
@@ -130,8 +116,7 @@ namespace DotNetOAuth.Messaging {
switch (message.Transport) {
case MessageTransport.Direct:
// This is a response to a direct message.
- this.SendDirectMessageResponse(message);
- break;
+ return this.SendDirectMessageResponse(message);
case MessageTransport.Indirect:
var directedMessage = message as IDirectedProtocolMessage;
if (directedMessage == null) {
@@ -145,8 +130,7 @@ namespace DotNetOAuth.Messaging {
if (directedMessage.Recipient == null) {
throw new ArgumentException(MessagingStrings.DirectedMessageMissingRecipient, "message");
}
- this.SendIndirectMessage(directedMessage);
- break;
+ return this.SendIndirectMessage(directedMessage);
default:
throw new ArgumentException(
string.Format(
@@ -363,7 +347,8 @@ namespace DotNetOAuth.Messaging {
/// Queues an indirect message for transmittal via the user agent.
/// </summary>
/// <param name="message">The message to send.</param>
- protected virtual void SendIndirectMessage(IDirectedProtocolMessage message) {
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
+ protected virtual Response SendIndirectMessage(IDirectedProtocolMessage message) {
if (message == null) {
throw new ArgumentNullException("message");
}
@@ -377,7 +362,7 @@ namespace DotNetOAuth.Messaging {
response = this.Create301RedirectResponse(message, fields);
}
- this.QueueIndirectOrResponseMessage(response);
+ return response;
}
/// <summary>
@@ -474,26 +459,11 @@ namespace DotNetOAuth.Messaging {
/// are sent in the response stream in querystring style.
/// </summary>
/// <param name="response">The message to send as a response.</param>
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
/// <remarks>
/// This method implements spec V1.0 section 5.3.
/// </remarks>
- protected abstract void SendDirectMessageResponse(IProtocolMessage response);
-
- /// <summary>
- /// Takes a message and temporarily stores it for sending as the hosting site's
- /// HTTP response to the current request.
- /// </summary>
- /// <param name="response">The message to store for sending.</param>
- protected void QueueIndirectOrResponseMessage(Response response) {
- if (response == null) {
- throw new ArgumentNullException("response");
- }
- if (this.queuedIndirectOrResponseMessage != null) {
- throw new InvalidOperationException(MessagingStrings.QueuedMessageResponseAlreadyExists);
- }
-
- this.queuedIndirectOrResponseMessage = response;
- }
+ protected abstract Response SendDirectMessageResponse(IProtocolMessage response);
/// <summary>
/// Prepares a message for transmit by applying signatures, nonces, etc.
diff --git a/src/DotNetOAuth/ServiceProvider.cs b/src/DotNetOAuth/ServiceProvider.cs
index 778f9df..10ea5a7 100644
--- a/src/DotNetOAuth/ServiceProvider.cs
+++ b/src/DotNetOAuth/ServiceProvider.cs
@@ -53,11 +53,6 @@ namespace DotNetOAuth {
public ServiceProviderDescription Description { get; private set; }
/// <summary>
- /// Gets the pending user agent redirect based message to be sent as an HttpResponse.
- /// </summary>
- public Response PendingRequest { get; private set; }
-
- /// <summary>
/// Gets or sets the channel to use for sending/receiving messages.
/// </summary>
internal OAuthChannel Channel { get; set; }
@@ -108,12 +103,16 @@ namespace DotNetOAuth {
return this.Channel.ReadFromRequest<DirectUserToServiceProviderMessage>(request);
}
- internal void SendAuthorizationResponse(DirectUserToServiceProviderMessage request) {
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="request"></param>
+ /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
+ internal Response SendAuthorizationResponse(DirectUserToServiceProviderMessage request) {
var authorization = new DirectUserToConsumerMessage(request.Callback) {
RequestToken = request.RequestToken,
};
- this.Channel.Send(authorization);
- this.PendingRequest = this.Channel.DequeueIndirectOrResponseMessage();
+ return this.Channel.Send(authorization);
}
internal RequestAccessTokenMessage ReadAccessTokenRequest() {