summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-01-27 08:01:49 -0800
committerAndrew <andrewarnott@gmail.com>2009-01-29 08:11:45 -0800
commitc701066381fc2c73bec4f63981d7637aa33b713b (patch)
tree31aef286b9b981d3c8eb1f59da64ec4e1c2a6a86
parent6da8acfa0ddc095ae3e9ba9fb884db53764c3f1d (diff)
downloadDotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.zip
DotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.tar.gz
DotNetOpenAuth-c701066381fc2c73bec4f63981d7637aa33b713b.tar.bz2
OpenIdChannel now processes response messages sent with HTTP 400 errors.
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj1
-rw-r--r--src/DotNetOpenAuth/Messaging/Channel.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/Accept400ErrorWebRequestHandlerWrappers.cs85
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs24
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>