为什么ASP.NET使用Transfer-Encoding头更换Content-Length头手动冲水的响应时? [英] Why is ASP.NET replacing a Content-Length header with a Transfer-Encoding header when manually flushing a response?

查看:591
本文介绍了为什么ASP.NET使用Transfer-Encoding头更换Content-Length头手动冲水的响应时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的Web应用程序(ASP.NET Web窗体)有一个页面将显示最近生成的PDF文件的用户。由于PDF文件有时是相当大的,我们已经实现了流的方式将其发送到以块的客户端浏览器。

Our web application (ASP.NET Web Forms) has a page that will display a recently generated PDF file to users. Because the PDF file is sometimes quite large, we've implemented a "streaming" approach to send it down to the client browser in chunks.

尽管大块下来发送数据,我们知道之前将其发送文件的完整大小,所以我们适当地设置Content-Length头。这已经在我们的生产环境中工作一段时间(并继续在我们的测试环境,其中一个几乎相同的配置工作)直到今天。报告的问题是,Chrome浏览器将试图打开PDF文件,但将与加载动画卡住挂起。

Despite sending the data down in chunks, we know the full size of the file prior to sending it, so we set the Content-Length header appropriately. This has been working in our production environment for awhile (and continues to work in our test environment with a virtually identical configuration) until today. The issue reported was that Chrome would attempt to open the PDF file but would hang with the "Loading" animation stuck.

由于一切都还在我们的测试环境工作正常,我可以使用Firebug来看看这是在两种环境下回来的响应头。在测试环境中,我看到一个适当的内容长度标头,而在生产已被替换为传输编码:分块头。 Chrome不喜欢这样,所以挂断。

Because everything was still working fine in our test environment I was able to use Firebug to take a look at the response headers that were coming back in both environments. In the test environment, I was seeing a proper 'Content-Length' header, while in production that had been replaced with a Transfer-Encoding: chunked header. Chrome doesn't like this, hence the hang-up.

我读过一些文章和帖子谈论Transfer-Encoding头如何显示没有提供Content-Length头的时候,但是我们指定了Content-Length头,一切似乎仍然在运行相同的工作code为测试服务器上的同一个PDF文件。

I've read some articles and posts talking about how the Transfer-Encoding header can show up when no Content-Length header is provided, but we are specifying the Content-Length header and everything still appears to work while running the same code for the same PDF file on a test server.

测试和生产服务器都运行IIS 7.5并且都启用了动态与静态的COM pression。

Both test and production servers are running IIS 7.5 and both have Dynamic and Static Compression enabled.

下面是有问题的code:

Here is the code in question:

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();
    }
}

我有幸看到我的本地工作站上相同的行为,以便使用调试器我已经能够看到传输编码:分块标头被调用时的第2次通过while循环设置同花顺。在这一点上,响应由响应达到萤火虫只显示Transfer-Encoding头在浏览器的时候同时有Content-Length头和Transfer-Encoding头,但不知何故。

I was fortunate to see the same behavior on my local workstation so using the debugger I have been able to see that the 'Transfer-Encoding: chunked' header is being set on the 2nd pass through the while loop during the call to 'Flush'. At that point, the response has both a Content-Length header and Transfer-Encoding header, but somehow by the time the response reaches the browser Firebug is only showing the Transfer-Encoding header.

更新

我想我已经跟踪下来使用下来发送数据的块并附加一个过滤器的Htt的presponse对象的组合(我们使用的过滤器来跟踪视图状态的大小被发送到每个页)。有没有在我们毫无意义时,发送一个PDF下降到浏览器,所以在这里清除过滤器解决了我们的问题,使用HTTP过滤器。我决定纯粹是为了挖得更深一些出于好奇,并已更新了这个问题应该谁都曾经绊倒在未来这个问题。

I think I've tracked this down to using a combination of sending the data down in "chunks" AND attaching a 'Filter' to the HttpResponse object (we were using a filter to track the size of viewstate being sent down to each page). There's no sense in us using an HTTP filter when sending a PDF down to the browser, so clearing the filter here has resolved our issue. I decided to dig in a little deeper purely out of curiosity and have updated this question should anyone else ever stumble onto this problem in the future.

我有一个简单的应用程序多达上AppHarbor重现该问题: http://transferencodingtest.apphb.com/ 。如果您同时检查使用过滤器?和发送以块?箱,你应该能看到传输编码:分块标头显示(使用Chrome开发工具,萤火虫,小提琴手,等等)。如果任何一个箱子的不检查,你会得到一个正确的Content-Length头。底层code是高达在GitHub上,所以你可以看到这是怎么回事幕后:

I've got a simple app up on AppHarbor that reproduces the issue: http://transferencodingtest.apphb.com/. If you check both the 'Use Filter?' and 'Send In Chunks?' boxes you should be able to see the 'transfer-encoding: chunked' header show up (using Chrome dev tools, Firebug, Fiddler, whatever). If either of the boxes are not checked, you'll get a proper content-length header. The underlying code is up on github so you can see what's going on behind the scenes:

https://github.com/appakz/TransferEncodingTest

请注意,要在本地瑞普你需要安装IIS 7.5中的本地网站(7还可以工作,我没有尝试过)。在ASP .NET开发服务器随Visual Studio不瑞普问题。

Note that to repro locally you'd need to setup a local website in IIS 7.5 (7 may also work, I haven't tried). The ASP .NET development server that ships with Visual Studio DOES NOT repro the issue.

我添加了一些细节到此处的博客文章:<一href=\"http://gruff$c$c.com/2012/01/02/content-length-header-replaced-with-transfer-encoding-chunked-in-asp-net/\"相对=nofollow>内容长度标头替换为传输编码:分块中的ASP .NET

I've added some more details to a blog post here: 'Content-Length' Header Replaced With 'Transfer-Encoding: Chunked' in ASP .NET

推荐答案

从的在MSDN上的一篇文章中似乎可以禁用分块编码:

From an article on MSDN it seems that you can disable chunked encoding:

appcmd set config /section:asp /enableChunkedEncoding:False

但它在 ASP设置,所以它可能不会适用于从ASP.NET处理程序生成的响应。

But it's mentioned under ASP settings, so it may not apply to a response generated from an ASP.NET handler.

这篇关于为什么ASP.NET使用Transfer-Encoding头更换Content-Length头手动冲水的响应时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆