Note that there are some explanatory texts on larger screens.

plurals
  1. POWeb API as a Proxy and Chunked Transfer Encoding
    text
    copied!<p> I have been playing around with using Web API (Web Host) as a proxy server and have run into an issue with how my Web API proxy handles responses with the "Transfer-Encoding: chunked" header. </p> <p>When bypassing the proxy, the remote resource sends the following response headers:</p> <pre class="lang-cs prettyprint-override"><code>Cache-Control:no-cache Content-Encoding:gzip Content-Type:text/html Date:Fri, 24 May 2013 12:42:27 GMT Expires:-1 Pragma:no-cache Server:Microsoft-IIS/8.0 Transfer-Encoding:chunked Vary:Accept-Encoding X-AspNet-Version:4.0.30319 X-Powered-By:ASP.NET </code></pre> <p>When going through my Web API based proxy, my request hangs unless I explicitly reset the TransferEncodingChunked property on the response header to false:</p> <pre class="lang-cs prettyprint-override"><code>response.Headers.TransferEncodingChunked = false; </code></pre> <p>I admit, I don't fully understand what impact setting the TransferEncodingChunked property has, but it seems strange to me that in order to make the proxy work as expected, I need to set this property to false when clearly the incoming response has a "Transfer-Encoding: chunked" header. I am also concerned about side effects to explicitly setting this property. Can anyone help me understand what is going on and why setting this property is required?</p> <p>UPDATE: So I did a little more digging into the difference in the response when going through the proxy vs. not. Whether I explicitly set the TransferEncodingChunked property to false, the response headers when coming through the proxy are exactly the same as when not going through the proxy. However, the response content is different. Here are a few samples (I turned off gzip encoding):</p> <pre class="lang-cs prettyprint-override"><code>// With TransferEncodingChunked = false 2d\r\n This was sent with transfer-encoding: chunked\r\n 0\r\n // Without explicitly setting TransferEncodingChunked This was sent with transfer-encoding: chunked </code></pre> <p>Clearly, the content sent with TransferEncodingChunked set to false is in fact transfer encoded. This is actually the correct response as it is what was received from the requested resource behind the proxy. What continues to be strange is the second scenario in which I don't explicitly set TransferEncodingChunked on the response (but it is in the response header received from the proxied service). Clearly, in this case, the response is NOT in fact transfer encoded by IIS, in spite of the fact that the actual response is. Strange...this is starting to feel like designed behavior (in which case, I'd love to know how / why) or a bug in IIS, ASP.Net, or Web API.</p> <p>Here is a simplified version of the code I am running:</p> <p>Proxy Web API application:</p> <pre class="lang-cs prettyprint-override"><code>// WebApiConfig.cs config.Routes.MapHttpRoute( name: "Proxy", routeTemplate: "{*path}", handler: HttpClientFactory.CreatePipeline( innerHandler: new HttpClientHandler(), // Routes the request to an external resource handlers: new DelegatingHandler[] { new ProxyHandler() } ), defaults: new { path = RouteParameter.Optional }, constraints: null ); // ProxyHandler.cs public class ProxyHandler : DelegatingHandler { protected override async System.Threading.Tasks.Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { // Route the request to my web application var uri = new Uri("http://localhost:49591" + request.RequestUri.PathAndQuery); request.RequestUri = uri; // For GET requests, somewhere upstream, Web API creates an empty stream for the request.Content property // HttpClientHandler doesn't like this for GET requests, so set it back to null before sending along the request if (request.Method == HttpMethod.Get) { request.Content = null; } var response = await base.SendAsync(request, cancellationToken); // If I comment this out, any response that already has the Transfer-Encoding: chunked header will hang in the browser response.Headers.TransferEncodingChunked = false; return response; } } </code></pre> <p>And my web application controller which creates a "chunked" response (also Web API):</p> <pre class="lang-cs prettyprint-override"><code>public class ChunkedController : ApiController { public HttpResponseMessage Get() { var response = Request.CreateResponse(HttpStatusCode.OK); var content = "This was sent with transfer-encoding: chunked"; var bytes = System.Text.Encoding.ASCII.GetBytes(content); var stream = new MemoryStream(bytes); response.Content = new ChunkedStreamContent(stream); return response; } } public class ChunkedStreamContent : StreamContent { public ChunkedStreamContent(Stream stream) : base(stream) { } protected override bool TryComputeLength(out long length) { length = 0L; return false; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload