IIS7 - Specifying content-length header in ASP cau

2019-04-25 05:41发布

问题:

I'm migrating a series of websites from an existing IIS5 server to a brand new IIS7 web server. One of the pages pulls a data file from a blob in the database and serves it to the end user:

Response.ContentType = rs("contentType")
Response.AddHeader "Content-Disposition", "attachment;filename=" & Trim(rs("docName"))&rs("suffix")' let the browser know the file name
Response.AddHeader "Content-Length", cstr(rs("docsize"))' let the browser know the file size

Testing this in the new IIS7 install, I get a "Connection Reset" error in both Internet Explorer and Firefox. The document is served up correctly if the Content-Length header is removed (but then the user won't get a useful progress bar).

Any ideas on how to correct this; whether it be a server configuration option or via code?

Edit 1: Did a bit more trial and error. The requests will succeed if both "Enable Buffering" and "Enable Chunked Encoding" are false. If either one is enabled the error occurs.

Edit 2: More trial and error testing; turns out that text files will work fine with the script; only binary files (images, pdfs, etc.) will fail. Still completely clueless otherwise.

回答1:

As already mentioned somewhere else: http://en.wikipedia.org/wiki/Chunked_transfer_encoding

It uses the Transfer-Encoding HTTP response header in place of the Content-Length header, which the protocol would otherwise require. Because the Content-Length header is not used, the server does not need to know the length of the content before it starts transmitting a response to the client (usually a web browser). Web servers can begin transmitting responses with dynamically-generated content before knowing the total size of that content.

In IIS7 this is enabled by default: http://technet.microsoft.com/en-us/library/cc730855(v=ws.10).aspx

To enable HTTP 1.1 chunked transfer encoding for the World Wide Web publishing service, use the following syntax:

appcmd set config /section:asp /enableChunkedEncoding:True|False

True enables HTTP 1.1 chunked transfer encoding whereas False disables HTTP 1.1 chunked transfer encoding. The default value is True.

We had the same problem, our solution: remove AddHeader "Content-Length"



回答2:

There are two options to make it work:

  1. Output the "Content-Size" header, instead of "Content-Length". Note not all clients will recognise that, but at least it works.

  2. (Preferred) Set Response.Buffer to True, then you can use the "Content-Length" header, and handle the "chunking" yourself (thus not taxing the ASP memory buffer):

The following works for me on IIS7, and seems to send file size info correctly to the browser.

Response.Buffer = True
Response.ContentType = "application/pdf"
Response.AddHeader "Content-Disposition", "attachment; filename=""yourfile.pdf"""

Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile "yourfile.pdf"

Response.AddHeader "Content-Length", objStream.Size

' Send file in chunks. '
lByteCount = 0
lChunkSize = 100000
While lByteCount < objStream.Size
  If lByteCount + lChunkSize > objStream.Size Then lChunkSize = objStream.Size - lByteCount
  Response.BinaryWrite objStream.Read(lChunkSize)
  Response.Flush ' Flush the buffer every 100KBytes '
  lByteCount = lByteCount + lChunkSize
Wend

objStream.Close
Set objStream = Nothing


回答3:

Encountered this same issue when migrating ASP code from a Windows 2003 server to Windows 2012 with IIS 8.5. The fix was to adjust the ASP code as follows:

From:

Response.Addheader "Content-Length", Size

To:

Response.Addheader "Content-Size", Size