Nasza aplikacja internetowa (ASP.NET Web Forms) ma stronę, która wyświetli ostatnio wygenerowany plik PDF dla użytkowników. Ponieważ plik PDF jest czasami dość duży, wprowadziliśmy podejście "strumieniowe", aby wysłać je do przeglądarki klienta w porcjach.Dlaczego program ASP.NET zastępuje nagłówek Content-Length nagłówkiem kodowania transferu podczas ręcznego płukania odpowiedzi?
Pomimo wysyłania danych w porcjach, znamy pełny rozmiar pliku przed jego wysłaniem, dlatego odpowiednio ustawiamy nagłówek Content-Length. To działało w naszym środowisku produkcyjnym przez jakiś czas (i nadal działa w naszym środowisku testowym z praktycznie identyczną konfiguracją) do dziś. Zgłoszono problem polegający na tym, że Chrome próbował otworzyć plik PDF, ale zawiesiłby się z zablokowaną animacją "Ładowanie".
Ponieważ wszystko działało bez zarzutu w naszym środowisku testowym, mogłem użyć Firebug, aby przyjrzeć się nagłówkom odpowiedzi, które powracały w obu środowiskach. W środowisku testowym widziałem odpowiedni nagłówek "Content-Length", podczas gdy w produkcji został on zastąpiony nagłówkiem Transfer-Encoding: chunked. Chrome tego nie lubi, stąd zawieszenie.
Czytałem niektóre artykuły i posty mówiące o tym, jak nagłówek Transfer-Encoding może się wyświetlać, gdy nie ma nagłówka Content-Length, ale my określamy nagłówek Content-Length i wszystko wydaje się działać podczas uruchamiania ten sam kod dla tego samego pliku PDF na serwerze testowym.
Zarówno serwery testowe, jak i produkcyjne korzystają z usług IIS 7.5, a obie mają włączoną funkcję dynamicznej i statycznej kompresji.
Oto kod w pytaniu:
var fileInfo = new FileInfo(fileToSendDown);
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "filename=test.pdf");
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
var buffer = new byte[1024];
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
int read;
while ((read = fs.Read(buffer, 0, 1024)) > 0)
{
if (!response.IsClientConnected) break;
Response.OutputStream.Write(buffer, 0, read);
Response.Flush();
}
}
miałem szczęście zobaczyć takie samo zachowanie na mojej lokalnej stacji roboczej tak pomocą debuggera udało mi się zobaczyć, że „Transfer-Encoding: pakietowego” nagłówek jest ustawiany na drugim przejściu przez pętlę while podczas połączenia z "Flush". W tym momencie odpowiedź ma zarówno nagłówek Content-Length, jak i nagłówek Transfer-Encoding, ale w pewnym momencie, gdy odpowiedź dotrze do przeglądarki Firebug pokazuje tylko nagłówek Transfer-Encoding.
UPDATE
myślę, że to w dół do śledzone za pomocą kombinacji wysyłania danych w „kawałki” I załączając „” filtru do obiektu HttpResponse (byliśmy przy użyciu filtra do śledzenia rozmiar obszaru wyświetlania jest wysyłany do każdej strony). Nie ma sensu używać filtru HTTP przy wysyłaniu pliku PDF do przeglądarki, więc wyczyszczenie filtra rozwiązało nasz problem. Postanowiłem zagłębić się nieco głębiej wyłącznie z ciekawości i zaktualizowałem to pytanie, gdyby ktokolwiek inny natknął się na ten problem w przyszłości.
Mam prostą aplikację na AppHarbor, która odtwarza problem: http://transferencodingtest.apphb.com/. Jeśli zaznaczysz zarówno "Użyj filtra?" i "Wyślij w kawałki?" w polach, powinieneś zobaczyć nagłówek "transfer-encoding: chunked" (za pomocą narzędzi do Chrome, Firebug, Fiddler, cokolwiek innego). Jeśli jedno z pól nie jest zaznaczone, otrzymasz odpowiedni nagłówek długości treści. Kod bazowym jest maksymalnie na github, dzięki czemu można zobaczyć, co dzieje się za kulisami:
https://github.com/appakz/TransferEncodingTest
Należy pamiętać, że do powtórzenia błędu lokalnie trzeba by skonfigurować lokalną witrynę w IIS 7.5 (7 może również pracować, Nie próbowałem). Serwer deweloperski ASP .NET dostarczany z programem Visual Studio NIE ROBISZ problemu.
Dodałem trochę więcej szczegółów na blogu tutaj: 'Content-Length' Header Replaced With 'Transfer-Encoding: Chunked' in ASP .NET
Wiem, że to stare pytanie, ale wykonując podobne badania natknąłem się na [ten znakomity post] (http://geekswithblogs.net/GruffCode/archive/2012/01/02/lsquocontent-lengthrsquo-header-replaced-withsls-transact-encoding-chunkedquo-in-asp- .net.aspx) wyjaśniające ten problem. Aby stworzyć ten problem, potrzeba określonych okoliczności. Mam nadzieję, że to pomoże przyszłemu czytelnikowi. – user158017
To jest wpis, który napisałem po zadaniu pytania, nie otrzymaniu odpowiedzi, a następnie w końcu wymyślić kilka kroków, aby konsekwentnie go odtworzyć. Zaktualizowałem oryginalne pytanie z linkami do przykładowej aplikacji, która je odtwarza, ale przypuszczam, że powinienem dodać także link do posta na blogu. –