Skip to content
This repository has been archived by the owner on Mar 20, 2019. It is now read-only.

Commit

Permalink
OpenIdChannel now processes response messages sent with HTTP 400 errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Jan 29, 2009
1 parent 6da8acf commit c701066
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/DotNetOpenAuth/DotNetOpenAuth.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetOpenAuth/Messaging/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected Channel(IMessageFactory messageTypeProvider, params IChannelBindingEle
/// 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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
24 changes: 24 additions & 0 deletions src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ private OpenIdChannel(IMessageFactory messageTypeProvider, IChannelBindingElemen
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>
Expand Down

0 comments on commit c701066

Please sign in to comment.