diff options
Diffstat (limited to 'src/DotNetOpenAuth')
-rw-r--r-- | src/DotNetOpenAuth/Configuration/UntrustedWebRequestElement.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs | 5 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Messaging/MessagingUtilities.cs | 25 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs | 47 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Yadis/DiscoveryResult.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Yadis/Yadis.cs | 6 |
6 files changed, 76 insertions, 11 deletions
diff --git a/src/DotNetOpenAuth/Configuration/UntrustedWebRequestElement.cs b/src/DotNetOpenAuth/Configuration/UntrustedWebRequestElement.cs index 461b8a8..89cd435 100644 --- a/src/DotNetOpenAuth/Configuration/UntrustedWebRequestElement.cs +++ b/src/DotNetOpenAuth/Configuration/UntrustedWebRequestElement.cs @@ -60,7 +60,7 @@ namespace DotNetOpenAuth.Configuration { /// <summary> /// Gets or sets the read/write timeout after which an HTTP request will fail. /// </summary> - [ConfigurationProperty(ReadWriteTimeoutConfigName, DefaultValue = "00:00:00.800")] + [ConfigurationProperty(ReadWriteTimeoutConfigName, DefaultValue = "00:00:01.500")] [PositiveTimeSpanValidator] public TimeSpan ReadWriteTimeout { get { return (TimeSpan)this[ReadWriteTimeoutConfigName]; } diff --git a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs index cfc122d..418f6b2 100644 --- a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs +++ b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs @@ -234,7 +234,10 @@ namespace DotNetOpenAuth.Messaging { if (this.form == null) { if (this.HttpMethod == "POST" && this.Headers[HttpRequestHeader.ContentType] == "application/x-www-form-urlencoded") { StreamReader reader = new StreamReader(this.InputStream); - long originalPosition = this.InputStream.Position; + long originalPosition = 0; + if (this.InputStream.CanSeek) { + originalPosition = this.InputStream.Position; + } this.form = HttpUtility.ParseQueryString(reader.ReadToEnd()); if (this.InputStream.CanSeek) { this.InputStream.Seek(originalPosition, SeekOrigin.Begin); diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index 852d79d..c024cdc 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -184,6 +184,31 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Adds a set of HTTP headers to an <see cref="HttpResponse"/> instance, + /// taking care to set some headers to the appropriate properties of + /// <see cref="HttpResponse" /> + /// </summary> + /// <param name="headers">The headers to add.</param> + /// <param name="response">The <see cref="HttpListenerResponse"/> instance to set the appropriate values to.</param> + internal static void ApplyHeadersToResponse(WebHeaderCollection headers, HttpListenerResponse response) { + ErrorUtilities.VerifyArgumentNotNull(headers, "headers"); + ErrorUtilities.VerifyArgumentNotNull(response, "response"); + + foreach (string headerName in headers) { + switch (headerName) { + case "Content-Type": + response.ContentType = headers[HttpResponseHeader.ContentType]; + break; + + // Add more special cases here as necessary. + default: + response.AddHeader(headerName, headers[headerName]); + break; + } + } + } + + /// <summary> /// Copies the contents of one stream to another. /// </summary> /// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param> diff --git a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs index 55cb4b6..bad582c 100644 --- a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs @@ -123,23 +123,56 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires(HttpContext.Current != null); ErrorUtilities.VerifyHttpContext(); - HttpContext.Current.Response.Clear(); - HttpContext.Current.Response.StatusCode = (int)this.Status; - MessagingUtilities.ApplyHeadersToResponse(this.Headers, HttpContext.Current.Response); + this.Send(HttpContext.Current); + } + + /// <summary> + /// Automatically sends the appropriate response to the user agent + /// and ends execution on the current page or handler. + /// </summary> + /// <param name="context">The context of the HTTP request whose response should be set. + /// Typically this is <see cref="HttpContext.Current"/>.</param> + /// <exception cref="ThreadAbortException">Thrown by ASP.NET in order to prevent additional data from the page being sent to the client and corrupting the response.</exception> + public virtual void Send(HttpContext context) { + Contract.Requires(context != null); + ErrorUtilities.VerifyArgumentNotNull(context, "context"); + + context.Response.Clear(); + context.Response.StatusCode = (int)this.Status; + MessagingUtilities.ApplyHeadersToResponse(this.Headers, context.Response); if (this.ResponseStream != null) { try { - this.ResponseStream.CopyTo(HttpContext.Current.Response.OutputStream); + this.ResponseStream.CopyTo(context.Response.OutputStream); } catch (HttpException ex) { - if (ex.ErrorCode == -2147467259 && HttpContext.Current.Response.Output != null) { + if (ex.ErrorCode == -2147467259 && context.Response.Output != null) { // Test scenarios can generate this, since the stream is being spoofed: // System.Web.HttpException: OutputStream is not available when a custom TextWriter is used. - HttpContext.Current.Response.Output.Write(this.Body); + context.Response.Output.Write(this.Body); } else { throw; } } } - HttpContext.Current.Response.End(); + + context.Response.End(); + } + + /// <summary> + /// Automatically sends the appropriate response to the user agent. + /// </summary> + /// <param name="response">The response to set to this message.</param> + public virtual void Send(HttpListenerResponse response) { + Contract.Requires(response != null); + ErrorUtilities.VerifyArgumentNotNull(response, "response"); + + response.StatusCode = (int)this.Status; + MessagingUtilities.ApplyHeadersToResponse(this.Headers, response); + if (this.ResponseStream != null) { + response.ContentLength64 = this.ResponseStream.Length; + this.ResponseStream.CopyTo(response.OutputStream); + } + + response.OutputStream.Close(); } /// <summary> diff --git a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs index 90495e2..01dae40 100644 --- a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs +++ b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs @@ -28,7 +28,7 @@ namespace DotNetOpenAuth.Yadis { if (finalResponse == null) { this.ContentType = initialResponse.ContentType; this.ResponseText = initialResponse.GetResponseString(); - this.IsXrds = ContentType.MediaType == ContentTypes.Xrds; + this.IsXrds = this.ContentType != null && this.ContentType.MediaType == ContentTypes.Xrds; } else { this.ContentType = finalResponse.ContentType; this.ResponseText = finalResponse.GetResponseString(); diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs index c3ae307..98bffc9 100644 --- a/src/DotNetOpenAuth/Yadis/Yadis.cs +++ b/src/DotNetOpenAuth/Yadis/Yadis.cs @@ -76,7 +76,7 @@ namespace DotNetOpenAuth.Yadis { Logger.Yadis.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); } } - if (url == null && response.ContentType.MediaType == ContentTypes.Html) { + if (url == null && response.ContentType != null && response.ContentType.MediaType == ContentTypes.Html) { url = FindYadisDocumentLocationInHtmlMetaTags(response.GetResponseString()); if (url != null) { Logger.Yadis.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); @@ -152,6 +152,10 @@ namespace DotNetOpenAuth.Yadis { /// <c>true</c> if the response constains an XRDS document; otherwise, <c>false</c>. /// </returns> private static bool IsXrdsDocument(CachedDirectWebResponse response) { + if (response.ContentType == null) { + return false; + } + if (response.ContentType.MediaType == ContentTypes.Xrds) { return true; } |