2013-05-24 15 views
10

Używam Web API (Web Host) jako serwera proxy i mam problem z tym, jak mój serwer Web API obsługuje odpowiedzi za pomocą "Transfer-Encoding" : chunked "nagłówek.Web API jako proxy i kodowane przesyłanie Kodowanie

Kiedy pominięciem pełnomocnika, zdalny zasób wysyła kolejne nagłówki odpowiedzi:

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 

Podczas przechodzenia przez mojego pełnomocnika w oparciu Web API, moja prośba rozłącza chyba że wyraźnie zresetować właściwość TransferEncodingChunked w nagłówku odpowiedzi na false :

response.Headers.TransferEncodingChunked = false; 

muszę przyznać, że nie w pełni zrozumieć, co ustawienie wpływ własnością TransferEncodingChunked ma, ale wydaje mi się, że dziwne, aby uczynić pracę proxy zgodnie z oczekiwaniami, trzeba ustawić tę właściwość na wartość false kiedy wyraźnie przychodząca odpowiedź ma nagłówek "Transfer-Encoding: chunked". Jestem również zaniepokojony efektami ubocznymi, które wyraźnie określają tę właściwość. Czy ktoś może mi pomóc zrozumieć, co się dzieje i dlaczego ustawienie tej właściwości jest wymagane?

AKTUALIZACJA: Zrobiłem więc więcej, aby sprawdzić różnicę w odpowiedzi, gdy przechodzę przez serwer proxy, a nie. Niezależnie od tego, czy jawnie ustawiono właściwość TransferEncodingChunked na wartość false, nagłówki odpowiedzi podczas przechodzenia przez serwer proxy są dokładnie takie same, jak w przypadku, gdy nie przechodzą przez proxy. Jednak treść odpowiedzi jest inna. Poniżej przedstawiono kilka przykładów (I wyłączone kodowania 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 

Oczywiste jest, że zawartość wysyłane z TransferEncodingChunked wartość fałsz w istocie przeniesienie zakodowany. Jest to właściwie poprawna odpowiedź, ponieważ jest to, co otrzymano z żądanego zasobu za proxy. Co jest nadal dziwne, to drugi scenariusz, w którym nie ustawiam jawnie metody TransferEncodingChunked w odpowiedzi (ale jest ona w nagłówku odpowiedzi odebranym z usługi proxy). Oczywiście w tym przypadku odpowiedź NIE jest w istocie przeniesiona zakodowana przez IIS, mimo że faktyczna odpowiedź jest. Dziwne ... to zaczyna się czuć jak zaprojektowane zachowanie (w którym to przypadku chciałbym wiedzieć jak/dlaczego) lub błąd w IIS, ASP.Net lub Web API.

Tutaj jest uproszczoną wersją kodu używam:

Web Proxy aplikacji 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; 
    } 
} 

A mój kontroler aplikacja internetowa, która tworzy "pakietowego" odpowiedź (również Web API):

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

Jak wyglądają nagłówki na prośbie wychodzącej (za pośrednictwem serwera proxy) po jej zawieszeniu? porównaj to z obejściem. – wal

Odpowiedz

6

Z punktu widzenia HttpClient chrupanie zawartości jest w zasadzie szczegółem transportu. Treść dostarczona przez response.Content jest zawsze usuwana dla Ciebie przez HttpClient.

Wygląda na to, że w interfejsie API sieci Web występuje błąd polegający na tym, że nie jest on poprawnie (ponownie) dzielony na treść, gdy zażąda tego właściwość response.Headers.TransferEncodingChunked podczas działania w IIS. Problem polega na tym, że proxy wysyła klientowi, poprzez nagłówki, że treść jest porwana, podczas gdy w rzeczywistości tak nie jest. Zgłaszałem błąd tutaj: https://aspnetwebstack.codeplex.com/workitem/1124

Myślę, że twoje obejście jest najlepszą opcją w tej chwili.

Należy również zauważyć, że istnieje tutaj wiele warstw, które prawdopodobnie nie zostały zaprojektowane/przetestowane pod kątem scenariuszy proxy (i mogą nie obsługiwać tego).Po stronie HttpClient, zwróć uwagę, że automatycznie rozpakuje i wykona przekierowania, chyba że wyłączysz to zachowanie. Jako minimum, będziemy chcieli, aby ustawić te dwie właściwości: 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

Na stronie WebAPI/IIS, znalazłeś przynajmniej jeden błąd, a to nie byłoby zaskakujące, aby znaleźć innych, jak również . Wystarczy uprzedzić, że mogą występować takie błędy, jak pisanie proxy za pomocą tych technologii poza głównymi przypadkami projektowania.

+0

Dzięki za szczegółową odpowiedź i zgłoszenie błędu. Dziękujemy również za słowa ostrożności dotyczące naszego podejścia. Zauważyliśmy problemy z właściwością AllowAutoRedirect. Nie myślałem o właściwości AutomaticDecompression i zajmie się tym. Dzięki! –

Powiązane problemy