diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-01-27 08:01:49 -0800 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2009-01-29 08:11:45 -0800 |
commit | c701066381fc2c73bec4f63981d7637aa33b713b (patch) | |
tree | 31aef286b9b981d3c8eb1f59da64ec4e1c2a6a86 | |
parent | 6da8acfa0ddc095ae3e9ba9fb884db53764c3f1d (diff) | |
download | DotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.zip DotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.tar.gz DotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.tar.bz2 |
OpenIdChannel now processes response messages sent with HTTP 400 errors.
4 files changed, 111 insertions, 1 deletions
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 4844153..a5dcf21 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -173,6 +173,7 @@ <Compile Include="OpenId\Association.cs" /> <Compile Include="OpenId\AssociationMemoryStore.cs" /> <Compile Include="OpenId\Associations.cs" /> + <Compile Include="OpenId\ChannelElements\Accept400ErrorWebRequestHandlerWrappers.cs" /> <Compile Include="OpenId\ChannelElements\BackwardCompatibilityBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\ExtensionsBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\IOpenIdExtensionFactory.cs" /> diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs index e70e5d6..e1fdffa 100644 --- a/src/DotNetOpenAuth/Messaging/Channel.cs +++ b/src/DotNetOpenAuth/Messaging/Channel.cs @@ -113,7 +113,7 @@ namespace DotNetOpenAuth.Messaging { /// This defaults to a straightforward implementation, but can be set /// to a mock object for testing purposes. /// </remarks> - public IDirectWebRequestHandler WebRequestHandler { get; set; } + public virtual IDirectWebRequestHandler WebRequestHandler { get; set; } /// <summary> /// Gets the binding elements used by this channel, in no particular guaranteed order. diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/Accept400ErrorWebRequestHandlerWrappers.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/Accept400ErrorWebRequestHandlerWrappers.cs new file mode 100644 index 0000000..67fd0cd --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/Accept400ErrorWebRequestHandlerWrappers.cs @@ -0,0 +1,85 @@ +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using System.IO; + using System.Net; + + internal class Accept400ErrorDirectWebRequestHandlerWrapper : IDirectWebRequestHandler { + private IDirectWebRequestHandler wrappedHandler; + + internal Accept400ErrorDirectWebRequestHandlerWrapper(IDirectWebRequestHandler wrappedHandler) { + ErrorUtilities.VerifyArgumentNotNull(wrappedHandler, "wrappedHandler"); + this.wrappedHandler = wrappedHandler; + } + + internal IDirectWebRequestHandler WrappedHandler { + get { return this.wrappedHandler; } + } + + #region IDirectWebRequestHandler Members + + public Stream GetRequestStream(HttpWebRequest request) { + return this.wrappedHandler.GetRequestStream(request); + } + + public DirectWebResponse GetResponse(HttpWebRequest request) { + try { + return this.wrappedHandler.GetResponse(request); + } catch (ProtocolException ex) { + WebException innerWeb = ex.InnerException as WebException; + if (innerWeb != null && innerWeb.Status == WebExceptionStatus.ProtocolError) { + HttpWebResponse httpResponse = innerWeb.Response as HttpWebResponse; + if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.BadRequest) { + // This is OK. The OpenID spec says that server errors be returned as HTTP 400, + // So we'll just swallow the exception and generate the message that's in the + // error response. + } + } + + // This isn't a recognized acceptable case. + throw; + } + } + + #endregion + } + + internal class Accept400ErrorDirectSslWebRequestHandlerWrapper : Accept400ErrorDirectWebRequestHandlerWrapper, IDirectSslWebRequestHandler { + private IDirectSslWebRequestHandler wrappedHandler; + + internal Accept400ErrorDirectSslWebRequestHandlerWrapper(IDirectSslWebRequestHandler wrappedHandler) + : base(wrappedHandler) { + this.wrappedHandler = wrappedHandler; + } + + #region IDirectSslWebRequestHandler Members + + public Stream GetRequestStream(HttpWebRequest request, bool requireSsl) { + return this.wrappedHandler.GetRequestStream(request, requireSsl); + } + + public DirectWebResponse GetResponse(HttpWebRequest request, bool requireSsl) { + try { + return this.wrappedHandler.GetResponse(request, requireSsl); + } catch (ProtocolException ex) { + WebException innerWeb = ex.InnerException as WebException; + if (innerWeb != null && innerWeb.Status == WebExceptionStatus.ProtocolError) { + HttpWebResponse httpResponse = innerWeb.Response as HttpWebResponse; + if (httpResponse != null && httpResponse.StatusCode == HttpStatusCode.BadRequest) { + // This is OK. The OpenID spec says that server errors be returned as HTTP 400, + // So we'll just swallow the exception and generate the message that's in the + // error response. + } + } + + // This isn't a recognized acceptable case. + throw; + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs index 1e78d79..217386b 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs @@ -117,6 +117,30 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { this.WebRequestHandler = new UntrustedWebRequestHandler(); } + public override IDirectWebRequestHandler WebRequestHandler { + get { + // Unwrap the handler we were originally assigned. + var wrappedHandler = (Accept400ErrorDirectWebRequestHandlerWrapper) base.WebRequestHandler; + return wrappedHandler.WrappedHandler; + } + set { + if (value == null) { + base.WebRequestHandler = null; + } + + // Wrap the handler with one that can injest HTTP 400 errors. + IDirectWebRequestHandler wrappedHandler; + IDirectSslWebRequestHandler sslHandler = value as IDirectSslWebRequestHandler; + if (sslHandler != null) { + wrappedHandler = new Accept400ErrorDirectSslWebRequestHandlerWrapper(sslHandler); + } else { + wrappedHandler = new Accept400ErrorDirectWebRequestHandlerWrapper(value); + } + + base.WebRequestHandler = wrappedHandler; + } + } + /// <summary> /// Gets the extension factory that can be used to register OpenID extensions. /// </summary> |