Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorroncain <roncain@microsoft.com>2012-04-02 23:05:33 +0400
committerroncain <roncain@microsoft.com>2012-04-03 18:12:23 +0400
commit06f52b894414a3581dc424884c02c4d666ae8a07 (patch)
tree15ca2c3e94b5b7a7af466d5c627d440c04c64a85 /src
parentf351672299a19e7571cb35ba24914e526bc181e1 (diff)
DevDiv 388456 -- WebHost should not use Transfer-Encoding chunked when content length is known
Diffstat (limited to 'src')
-rw-r--r--src/System.Web.Http.WebHost/HttpControllerHandler.cs33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/System.Web.Http.WebHost/HttpControllerHandler.cs b/src/System.Web.Http.WebHost/HttpControllerHandler.cs
index b6b47c71..3e00b2f5 100644
--- a/src/System.Web.Http.WebHost/HttpControllerHandler.cs
+++ b/src/System.Web.Http.WebHost/HttpControllerHandler.cs
@@ -278,12 +278,19 @@ namespace System.Web.Http.WebHost
if (response.Content != null)
{
- CopyHeaders(response.Content.Headers, httpContextBase);
-
- // Select output buffering by the kind of content
+ // Select output buffering based on the kind of HttpContent.
+ // This is done before CopyHeaders because the ContentLength
+ // property getter will evaluate the content length and set
+ // the Content-Length header if it has not already been set.
+ // Doing this before CopyHeaders ensures the headers contain a
+ // valid Content-Length before they are copied to HttpContextBase.
+ // Unless HttpContextBase headers contain a positive Content-Length,
+ // the Transfer-Encoding for streamed output will be chunked.
isBuffered = IsOutputBufferingNecessary(response.Content);
httpResponseBase.BufferOutput = isBuffered;
+ CopyHeaders(response.Content.Headers, httpContextBase);
+
responseTask = response.Content.CopyToAsync(httpResponseBase.OutputStream);
}
else
@@ -328,24 +335,24 @@ namespace System.Web.Http.WebHost
});
}
- private static bool IsOutputBufferingNecessary(HttpContent httpContent)
+ /// <summary>
+ /// Determines whether the given <see cref="HttpContent"/> should use a buffered response.
+ /// </summary>
+ /// <param name="httpContent">The <see cref="HttpContent"/> of the response.</param>
+ /// <returns>A value of <c>true</c> indicates buffering should be used, otherwise a streamed response should be used.</returns>
+ internal static bool IsOutputBufferingNecessary(HttpContent httpContent)
{
- // Never buffer StreamContent. Either it's already buffered or
- // is of indeterminate length. Neither calls for us to buffer.
- if (httpContent == null || httpContent is StreamContent)
- {
- return false;
- }
+ Contract.Assert(httpContent != null);
- // Any content that knows its ContentLength is assumed to have
- // buffered it already.
+ // Any HttpContent that knows its length is presumably already buffered internally.
long? contentLength = httpContent.Headers.ContentLength;
if (contentLength.HasValue && contentLength.Value >= 0)
{
return false;
}
- return true;
+ // Content length is null or -1 (meaning not known). Buffer any HttpContent except StreamContent.
+ return !(httpContent is StreamContent);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Caller becomes owner")]