diff options
Diffstat (limited to 'src')
4 files changed, 49 insertions, 12 deletions
diff --git a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs index 59bd4dd..d81ce17 100644 --- a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs @@ -35,10 +35,18 @@ namespace DotNetOpenAuth.Messaging { /// Throws an internal error exception. /// </summary> /// <param name="errorMessage">The error message.</param> + /// <returns>Nothing. But included here so callers can "throw" this method for C# safety.</returns> /// <exception cref="InternalErrorException">Always thrown.</exception> [Pure] - internal static void ThrowInternal(string errorMessage) { - VerifyInternal(false, errorMessage); + internal static Exception ThrowInternal(string errorMessage) { + // Since internal errors are really bad, take this chance to + // help the developer find the cause by breaking into the + // debugger if one is attached. + if (Debugger.IsAttached) { + Debugger.Break(); + } + + throw new InternalErrorException(errorMessage); } /// <summary> @@ -52,14 +60,7 @@ namespace DotNetOpenAuth.Messaging { Contract.Ensures(condition); Contract.EnsuresOnThrow<InternalErrorException>(!condition); if (!condition) { - // Since internal errors are really bad, take this chance to - // help the developer find the cause by breaking into the - // debugger if one is attached. - if (Debugger.IsAttached) { - Debugger.Break(); - } - - throw new InternalErrorException(errorMessage); + ThrowInternal(errorMessage); } } diff --git a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs index e8d8fe1..cc991cd 100644 --- a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs @@ -140,6 +140,7 @@ namespace DotNetOpenAuth.Messaging { // We don't want to blindly set all ServicePoints to not use the Expect header // as that would be a security hole allowing any visitor to a web site change // the web site's global behavior when calling that host. + Logger.Http.InfoFormat("HTTP POST to {0} resulted in 417 Expectation Failed. Changing ServicePoint to not use Expect: Continue next time.", request.RequestUri); request.ServicePoint.Expect100Continue = false; // TODO: investigate that CAS may throw here // An alternative to ServicePoint if we don't have permission to set that, @@ -179,6 +180,31 @@ namespace DotNetOpenAuth.Messaging { #endregion /// <summary> + /// Determines whether an exception was thrown because of the remote HTTP server returning HTTP 417 Expectation Failed. + /// </summary> + /// <param name="ex">The caught exception.</param> + /// <returns> + /// <c>true</c> if the failure was originally caused by a 417 Exceptation Failed error; otherwise, <c>false</c>. + /// </returns> + internal static bool IsExceptionFrom417ExpectationFailed(Exception ex) { + while (ex != null) { + WebException webEx = ex as WebException; + if (webEx != null) { + HttpWebResponse response = webEx.Response as HttpWebResponse; + if (response != null) { + if (response.StatusCode == HttpStatusCode.ExpectationFailed) { + return true; + } + } + } + + ex = ex.InnerException; + } + + return false; + } + + /// <summary> /// Initiates a POST request and prepares for sending data. /// </summary> /// <param name="request">The HTTP request with information about the remote party to contact.</param> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs index a37c8c7..85c0096 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.ChannelElements; @@ -209,6 +210,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { throw new ProtocolException(MessagingStrings.UnexpectedMessageReceivedOfMany); } } catch (ProtocolException ex) { + // If the association failed because the remote server can't handle Expect: 100 Continue headers, + // then our web request handler should have already accomodated for future calls. Go ahead and + // immediately make one of those future calls now to try to get the association to succeed. + if (StandardWebRequestHandler.IsExceptionFrom417ExpectationFailed(ex)) { + return this.CreateNewAssociation(provider, associateRequest, retriesRemaining - 1); + } + // Since having associations with OPs is not totally critical, we'll log and eat // the exception so that auth may continue in dumb mode. Logger.OpenId.ErrorFormat("An error occurred while trying to create an association with {0}. {1}", provider.Endpoint, ex); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js index 2a58425..6e5d7dd 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js @@ -726,8 +726,10 @@ function Uri(url) { var queryStringPairs = this.queryString.split('&'); for (var i = 0; i < queryStringPairs.length; i++) { - var pair = queryStringPairs[i].split('='); - this.Pairs.push(new KeyValuePair(unescape(pair[0]), unescape(pair[1]))) + var equalsAt = queryStringPairs[i].indexOf('='); + left = (equalsAt >= 0) ? queryStringPairs[i].substring(0, equalsAt) : null; + right = (equalsAt >= 0) ? queryStringPairs[i].substring(equalsAt + 1) : queryStringPairs[i]; + this.Pairs.push(new KeyValuePair(unescape(left), unescape(right))); } }; |