diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-05-07 22:20:06 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-05-07 22:20:06 -0700 |
commit | 448c6dc2e352a49054358907abec3f9bfca3cf13 (patch) | |
tree | b89610facde118a7de372a323c8f9740b47a3779 | |
parent | 1d397e17442cfec1e95fd619ff0057227df39561 (diff) | |
download | DotNetOpenAuth-448c6dc2e352a49054358907abec3f9bfca3cf13.zip DotNetOpenAuth-448c6dc2e352a49054358907abec3f9bfca3cf13.tar.gz DotNetOpenAuth-448c6dc2e352a49054358907abec3f9bfca3cf13.tar.bz2 |
Getting closer to a WebServer client flow.
5 files changed, 90 insertions, 14 deletions
diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs index 03a8e6c..4bba733 100644 --- a/src/DotNetOpenAuth/Messaging/Channel.cs +++ b/src/DotNetOpenAuth/Messaging/Channel.cs @@ -635,6 +635,7 @@ namespace DotNetOpenAuth.Messaging { protected virtual OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) { Contract.Requires<ArgumentNullException>(message != null); Contract.Requires<ArgumentException>(message.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient); + Contract.Requires<ArgumentException>((message.HttpMethods & (HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.PostRequest)) != 0, "Neither GET nor POST are allowed for this message."); Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null); Contract.Assert(message != null && message.Recipient != null); @@ -642,10 +643,25 @@ namespace DotNetOpenAuth.Messaging { Contract.Assert(message != null && message.Recipient != null); var fields = messageAccessor.Serialize(); - // First try creating a 301 redirect, and fallback to a form POST - // if the message is too big. - OutgoingWebResponse response = this.Create301RedirectResponse(message, fields); - if (response.Headers[HttpResponseHeader.Location].Length > IndirectMessageGetToPostThreshold) { + OutgoingWebResponse response = null; + bool tooLargeForGet = false; + if ((message.HttpMethods & HttpDeliveryMethods.GetRequest) == HttpDeliveryMethods.GetRequest) { + // First try creating a 301 redirect, and fallback to a form POST + // if the message is too big. + response = this.Create301RedirectResponse(message, fields); + tooLargeForGet = response.Headers[HttpResponseHeader.Location].Length > IndirectMessageGetToPostThreshold; + } + + // Make sure that if the message is too large for GET that POST is allowed. + if (tooLargeForGet) { + ErrorUtilities.VerifyProtocol( + (message.HttpMethods & HttpDeliveryMethods.PostRequest) == HttpDeliveryMethods.PostRequest, + "Message too large for a HTTP GET, and HTTP POST is not allowed for this message type."); + } + + // If GET didn't work out, for whatever reason... + if (response == null || tooLargeForGet) + { response = this.CreateFormPostResponse(message, fields); } @@ -871,7 +887,7 @@ namespace DotNetOpenAuth.Messaging { var messageAccessor = this.MessageDescriptions.GetAccessor(requestMessage); var fields = messageAccessor.Serialize(); - HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(requestMessage.Recipient); + var httpRequest = (HttpWebRequest)WebRequest.Create(requestMessage.Recipient); httpRequest.CachePolicy = this.CachePolicy; httpRequest.Method = "POST"; diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapChannel.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapChannel.cs index 4cfffbf..fb6841c 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapChannel.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapChannel.cs @@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; + using System.Net; using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; @@ -44,6 +45,30 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { } /// <summary> + /// Prepares an HTTP request that carries a given message. + /// </summary> + /// <param name="request">The message to send.</param> + /// <returns> + /// The <see cref="HttpWebRequest"/> prepared to send the request. + /// </returns> + /// <remarks> + /// This method must be overridden by a derived class, unless the <see cref="RequestCore"/> method + /// is overridden and does not require this method. + /// </remarks> + protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) { + HttpWebRequest httpRequest; + if ((request.HttpMethods & HttpDeliveryMethods.GetRequest) != 0) { + httpRequest = InitializeRequestAsGet(request); + } else if ((request.HttpMethods & HttpDeliveryMethods.PostRequest) != 0) { + httpRequest = InitializeRequestAsPost(request); + } else { + throw new NotSupportedException(); + } + + return httpRequest; + } + + /// <summary> /// Gets the protocol message that may be in the given HTTP response. /// </summary> /// <param name="response">The response that is anticipated to contain an protocol message.</param> @@ -86,10 +111,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { typeof(Messages.UnauthorizedResponse), typeof(Messages.AssertionRequest), typeof(Messages.AssertionSuccessResponse), - typeof(Messages.AssertionFailedResponse), - typeof(Messages.ClientAccountUsernamePasswordRequest), - typeof(Messages.ClientAccountUsernamePasswordSuccessResponse), - typeof(Messages.ClientAccountUsernamePasswordFailedResponse), + typeof(Messages.ClientCredentialsRequest), typeof(Messages.RichAppRequest), typeof(Messages.RichAppResponse), typeof(Messages.RichAppAccessTokenRequest), diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs index d1deaa9..2dc6ca7 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs @@ -19,7 +19,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// Initializes a new instance of the <see cref="AssertionSuccessResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal AssertionSuccessResponse(ClientAccountUsernamePasswordRequest request) + internal AssertionSuccessResponse(ClientCredentialsRequest request) : base(request) { } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAgent/UserAgentFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UserAgent/UserAgentFailedResponse.cs new file mode 100644 index 0000000..8f08739 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UserAgent/UserAgentFailedResponse.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------- +// <copyright file="UserAgentFailedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + internal class UserAgentFailedResponse : MessageBase { + /// <summary> + /// A constant parameter that indicates the user refused to grant the requested authorization. + /// </summary> + [MessagePart(Protocol.error, IsRequired = true)] + private const string ErrorReason = Protocol.user_denied; + + internal UserAgentFailedResponse(Uri clientCallback, Version version) + : base(version, MessageTransport.Indirect, clientCallback) { + } + + /// <summary> + /// Gets or sets the state of the client that was supplied to the Authorization Server. + /// </summary> + /// <value> + /// An opaque value that Clients can use to maintain state associated with the authorization request. + /// </value> + /// <remarks> + /// If this value is present, the Authorization Server MUST return it to the Client's callback URL. + /// </remarks> + [MessagePart(Protocol.state, IsRequired = false, AllowEmpty = true)] + public string ClientState { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppRequest.cs index 790f30a..4b5eca7 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppRequest.cs @@ -25,12 +25,13 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// Initializes a new instance of the <see cref="WebAppRequest"/> class. /// </summary> - /// <param name="userAuthorizationEndpoint">The Authorization Server's user authorization URL to direct the user to.</param> + /// <param name="authorizationEndpoint">The Authorization Server's user authorization URL to direct the user to.</param> /// <param name="version">The protocol version.</param> - internal WebAppRequest(Uri userAuthorizationEndpoint, Version version) - : base(version, MessageTransport.Indirect, userAuthorizationEndpoint) { - Contract.Requires<ArgumentNullException>(userAuthorizationEndpoint != null); + internal WebAppRequest(Uri authorizationEndpoint, Version version) + : base(version, MessageTransport.Indirect, authorizationEndpoint) { + Contract.Requires<ArgumentNullException>(authorizationEndpoint != null); Contract.Requires<ArgumentNullException>(version != null); + this.HttpMethods = HttpDeliveryMethods.GetRequest; } /// <summary> |