2013-05-24 16 views
10

Web API(Web Host)をプロキシサーバーとして使用して遊んでいて、Web APIプロキシが「Transfer-Encoding :チャンクされた "ヘッダ。プロキシとチャンク転送エンコードとしてのWeb API

プロキシをバイパスした場合、リモートリソースには、次の応答ヘッダを送信します。

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 

私のWeb APIベースのプロキシを経由する場合は、私が明示的にfalseにレスポンスヘッダにTransferEncodingChunkedプロパティをリセットしない限り、私の要求がハングアップ:

response.Headers.TransferEncodingChunked = false; 

私は認める、私は完全に持っているTransferEncodingChunkedプロパティを設定するどのような影響を理解していないが、予想通り、プロキシの仕事を作るために、私は、このプロパティをfalseに設定する必要があるように私には奇妙に思えます明らかに入ってくる応答に「Transfer-Encoding:chunked」ヘッダーがある場合。私はこのプロパティを明示的に設定することによる副作用も懸念しています。誰が私に何が起こっているのか、なぜこのプロパティを設定する必要があるのか​​理解するのを助けることができますか?

更新:私は、プロキシを通過するときの応答の違いを少し掘り下げました。 TransferEncodingChunkedプロパティを明示的にfalseに設定するかどうかにかかわらず、プロキシを経由するときの応答ヘッダーは、プロキシを経由しないときとまったく同じです。ただし、応答内容は異なります。ここではいくつかのサンプル(IはGZIPエンコーディングをオフ)である:

// 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 

は明らかに、falseにTransferEncodingChunkedセットで送信されたコンテンツは、エンコードされた実際の転送です。これは、プロキシの背後にある要求されたリソースから受け取ったものであるため、実際は正しい応答です。引き続き奇妙なことは、応答にTransferEncodingChunkedを明示的に設定しないという2番目のシナリオです(ただし、プロキシされたサービスから受信した応答ヘッダーにあります)。明らかに、このケースでは、実際の応答が実際であるにもかかわらず、IISによってコード化された応答は実際には転送されません。奇妙な...これは、設計された動作(その場合、私はどのように/なぜか)、またはIIS、ASP.Net、またはWeb APIのバグを知りたいと思っています。ここで

は、私が実行しているコードの簡易版である:

プロキシウェブAPIアプリケーション:

// 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<HttpResponseMessage> 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; 
    } 
} 

そして "チャンク" 応答(もウェブAPI)を作成し、自分のWebアプリケーションのコントローラ:

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; 
    } 
} 
+0

発信(プロキシ)要求がハングアップしたときに、ヘッダーはどのように見えますか?これをバイパスされたものと比較してください。 – wal

答えて

6

HttpClientの観点からは、コンテンツチャンクは基本的にトランスポートの詳細です。 response.Contentによって提供されるコンテンツは、HttpClientによって常にチャンクされなくなります。

Web APIには、IISで実行されているときにresponse.Headers.TransferEncodingChunkedプロパティによってリクエストされたときにコンテンツを正しくチャンクしないというバグがあるようです。したがって問題は、プロキシがヘッダーを介してクライアントに実際にはコンテンツがチャンクされていないことを伝えていることです。私はここにバグを提出しました: https://aspnetwebstack.codeplex.com/workitem/1124

あなたの回避策は現時点では最良の選択肢だと思います。

また、プロキシシナリオ用に設計/テストされていない可能性があります(サポートしていない可能性があります)。HttpClient側では、その動作をオフにしない限り、自動的に解凍してリダイレクトに従うことに注意してください。最低でも、この2つのプロパティを設定することをお勧めします:WEBAPI/IIS側で http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.allowautoredirect.aspx http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.automaticdecompression.aspx

を、あなたは、少なくとも一つのバグを見つけた、と同様に他の人を見つけるために、思わぬことではないでしょう。このようなバグが主な設計ユースケースの外でこれらのテクノロジーを使用してプロキシを作成している可能性があります。

+0

詳細な回答とバグレポートをありがとう。また、私たちのアプローチについて注意していただきありがとうございます。私たちはAllowAutoRedirectプロパティの問題に気付いていました。 AutomaticDecompressionプロパティについては考えていなかったので、それを調べます。ありがとう! –

関連する問題