Content-Length header ignored?

B

Bob Murdoch

I'm using the following to send a binary file to a user:

Response.AddHeader('Content-Disposition','attachment;filename=' +
Request('FileName') + ';');

var vType = 'application/octetstream';
var vFileName = String(Request('FileName')).toLowerCase();
if (vFileName.indexOf('.xls') > -1)
vType = 'application/vnd.ms-excel';
if (vFileName.indexOf('.csv') > -1)
vType = 'application/vnd.ms-excel';
else if (vFileName.indexOf('.pdf') > -1)
vType = 'application/pdf';
else if (vFileName.indexOf('.zip') > -1)
vType = 'application/zip';
else if (vFileName.indexOf('.doc') > -1)
vType = 'application/vnd.msword';

Response.ContentType = vType;
Response.Expires = 0;

var vStream = Server.CreateObject("ADODB.Stream");
vStream.Open();
vStream.Type = 1; //binary
vStream.LoadFromFile(vPath + Request('TempFile')); //must be full server
path and file name
Response.AddHeader('Content-Length', vStream.Size);
Response.BinaryWrite(vStream.Read());
vStream.Close;
vStream = null;
Response.End;

I have verified that the vStream.Size is correct at that point in the
script. However, in the IE download dialog, it only says "Estimated Time
Left: not known". I have also tried "AddHeader('Content-Length',
vStream.Size.ToString) just in case there was some conversion problem with
the size, but there was no change.

Is there some other way of telling the browser how big the file is?

tia,

Bob M..
 
A

Anthony Jones

Bob Murdoch said:
I'm using the following to send a binary file to a user:

Response.AddHeader('Content-Disposition','attachment;filename=' +
Request('FileName') + ';');

var vType = 'application/octetstream';
var vFileName = String(Request('FileName')).toLowerCase();
if (vFileName.indexOf('.xls') > -1)
vType = 'application/vnd.ms-excel';
if (vFileName.indexOf('.csv') > -1)
vType = 'application/vnd.ms-excel';
else if (vFileName.indexOf('.pdf') > -1)
vType = 'application/pdf';
else if (vFileName.indexOf('.zip') > -1)
vType = 'application/zip';
else if (vFileName.indexOf('.doc') > -1)
vType = 'application/vnd.msword';

Response.ContentType = vType;
Response.Expires = 0;

var vStream = Server.CreateObject("ADODB.Stream");
vStream.Open();
vStream.Type = 1; //binary
vStream.LoadFromFile(vPath + Request('TempFile')); //must be full server
path and file name
Response.AddHeader('Content-Length', vStream.Size);
Response.BinaryWrite(vStream.Read());
vStream.Close;
vStream = null;
Response.End;

I have verified that the vStream.Size is correct at that point in the
script. However, in the IE download dialog, it only says "Estimated Time
Left: not known". I have also tried "AddHeader('Content-Length',
vStream.Size.ToString) just in case there was some conversion problem with
the size, but there was no change.

Is there some other way of telling the browser how big the file is?

You should not attempt to add a content-length header yourself. When
Response buffering is turned off IIS will use chunked encoding, in which
case a Content-Length header at the beginning of the response is invalid.
IIS will ensure the appropriate header is placed at the end of response.

When buffering is turned on IIS will add the header itself once the script
has completed the response. In this case nothing is sent until the script
is finished (unless you flush the buffer) so the header will precede the
content.

Since you're not chunking the stream into the response you may as well
ensure Response.Buffer is true and ditch the attempt to set the content
length.

How big is the file anyway?
 
B

Bob Murdoch

Anthony Jones said:
You should not attempt to add a content-length header yourself. When
Response buffering is turned off IIS will use chunked encoding, in which
case a Content-Length header at the beginning of the response is invalid.
IIS will ensure the appropriate header is placed at the end of response.

When buffering is turned on IIS will add the header itself once the script
has completed the response. In this case nothing is sent until the script
is finished (unless you flush the buffer) so the header will precede the
content.

Since you're not chunking the stream into the response you may as well
ensure Response.Buffer is true and ditch the attempt to set the content
length.

How big is the file anyway?

In some cases the file is <50kb, but I noticed the lack of progress bar when
testing a file of 8.9MB. In fact, for a file that size I actually had to
resort to chunking the stream in the response as you mentioned. Is there a
way to set the file size when chunking?

thanks,

Bob M..
 
A

Anthony Jones

Bob Murdoch said:
In some cases the file is <50kb, but I noticed the lack of progress bar when
testing a file of 8.9MB. In fact, for a file that size I actually had to
resort to chunking the stream in the response as you mentioned.

On IIS6 by default the max buffer size is 4MB so anything larger would
needed chopping up.
Is there a way to set the file size when chunking?

No. In ASP you would need a way to guarantee to the Response object that
your code will send exactly the number of bytes you specify. ASP provides
no facility for you to do that, it was designed for dynamic content whose
length is unknown untill the script completes.

What link speed are you using? On some broadband connections 8.9MB may well
still come down quick enough not to warrant a progress bar. Also some
browsers will continue with downloading the resource whilst the save dialog
is on screen.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top