Successfully Stream a PDF to browser through HTTPS

In this article I will try to explain you the technique of displaying file in the browser using Byte Array through HTTPS. Reason behind writing this article is, I need to implement this functionality in my application I invested lots of hours behind this and finally I found the solution.

Problem Description

I have a popup window in which to display a PDF file. This PDF is coming from Web Service call, which returns us a Byte Array. All ok so far, byte array is populated.

Byte Array is passed back as a MemoryStream. That MemoryStream is then sent out through ASP.Net’s Response object after setting the ContentType=”application/pdf”.

In development, I had no problems using the following code with HTTP:

Response.Clear();

//Send the file to the output stream

Response.Buffer = true;

//Try and ensure the browser always opens the file and doesn’t just prompt to “open/save”.

Response.AddHeader(“Content-Length”, ByteArray.Length.ToString());

Response.AddHeader(“Content-Disposition”, “inline; filename=” + PDFName);

Response.AddHeader(“Expires”,”0″);

Response.AddHeader(“Pragma”,”cache”);

Response.AddHeader(“Cache-Control”,”private”);

//Set the output stream to the correct content type (PDF).

Response.ContentType = “application/pdf”;

//Output the file

Response.BinaryWrite(ByteArray);

//Flushing the Response to display the serialized data

//to the client browser.

Response.Flush();

try{Response.End();}

catch{}

Everything seems fine until I moved it to our integration server which has HTTPS enabled.

Suddenly, I’m getting a dialog box stating “This page contains both secure and nonsecure items. Do you want to display the nonsecure items?” Clicking either Yes or No continued to display the document as normal, but there seemed no solution to getting rid of the dialog box.

If you do a Google on this text, you’ll only get back about four pages and one Groups post. Do enough digging and you’ll eventually find the following two MSDN articles:
http://support.microsoft.com/default.aspx?scid=kb;en-us;300443
http://support.microsoft.com/?kbid=321532

The second post leads you to the solution. Notice that the code above includes the length of the byte array being written to the output stream? I did, so I believed that ASP.Net would correctly populate the HTTP Headers indicating the length of the output. Unfortunately, this was a bad assumption. It turns out that IE6 requires the use of the “Accept-Ranges” HTTP header when HTTPS is used. Microsoft even acknowledges that there may be a bug in IE6. Since I am navigating to the PDF display page using GET and not POST, I can assume from the KB article that a POST wouldn’t work even after adding the “Accept-Ranges” HTTP Header.

Here’s the corrected code:

Response.Clear();

//Send the file to the output stream

Response.Buffer = true;

Response.AddHeader(“Accept-Header”,resultSet.Document.Length.ToString());

//Try and ensure the browser always opens the file and doesn’t just prompt to “open/save”.

Response.AddHeader(“Content-Length”, ByteArray.Length.ToString());

Response.AddHeader(“Content-Disposition”, “inline; filename=” + PDFName);

Response.AddHeader(“Expires”,”0″);

Response.AddHeader(“Pragma”,”cache”);

Response.AddHeader(“Cache-Control”,”private”);

//Set the output stream to the correct content type (PDF).

Response.ContentType = “application/pdf”;

Response.AddHeader(“Accept-Ranges”, “bytes”);

//Output the file

Response.BinaryWrite(ByteArray);

//Flushing the Response to display the serialized data

//to the client browser.

Response.Flush();

try{Response.End();}

catch{}

References:

http://blogs.ittoolbox.com/visualbasic/dotnet/archives/successfully-stream-a-pdf-through-https-1554

If you are looking for detail information on Content-Disposition Header, you can visit following link.

http://www.imc.org/ietf-822/old-archive1/msg03620.html

About these ads

4 Responses to Successfully Stream a PDF to browser through HTTPS

  1. lee says:

    Just wanted to say “thank you” to your posting. It works!

  2. Tony Smith says:

    This fix worked like a dream. Thanks for your analysis and clear instructions!

  3. Chen says:

    It works and helps a lot! Thank you.

  4. I ran into this exact problem a few years ago – atually, before IE7 existed. Looking back at the code I wrote, I must have thought it was the norm to include the extra accept-ranges header, though I have not done so in more recent code. I don’t any sites right now that would pass PDFs through https, so no problems at this point. Glad that you found an answer that worked for you. John

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: