Ok. So this wasn't a bug in either IIS or ASP.NET...it was a bug in my code.
The ASP.NET page reads a PDF file from the disk into a byte array (byte[]) and then squirts it out through the HttpResponse using BinaryWrite(). Here's the code...
private void WriteRequestedDocumentToResponse(string filename) { Response.AddHeader( "Content-Disposition", “attachment;filename=" + filename); Response.BinaryWrite(GetFileAsByteArray(pathToFile)); }
This code has been in production and working for a few weeks and then yesterday the client posted a new version of the PDF file and all of a sudden Acrobat started saying “There was an error opening this document. The file is damaged and could not be repaired.“ My first instinct was to say “well, the pdf's messed up“ but when the file got downloaded and saved to my local disk, it kept coming out about 1kb bigger than it was supposed to be.
My second thought was to suspect the GetFileAsByteArray() method even though that method had been used in a bunch of different projects without incident.
private byte[] GetFileAsByteArray(string fileName) { FileStream fs; fs=File.Open(fileName, FileMode.Open, FileAccess.Read); byte[] buffer=new byte[fs.Length]; fs.Read(buffer, 0, System.Convert.ToInt32(fs.Length)); fs.Close(); return buffer; }
So, looking at the GetFileAsByteArray() method, had a moment of panic looking at the Convert.ToInt32 line. I'm like, “oh...dammit! fs.Length is a 'long' and fs.Read() is changing that value to an int. Crap! It's trimming a bunch of stuff because the int value is maxxing out. After checking what the max value of an Int32 is and running some unit tests, well, let's just say that that turned out to be utter foolishness on my part. This code will support files bigger than 2GB. Well, this method checks out.
So, what about those extra bytes that sometimes get tagged onto the downloaded PDFs? I opened up the non-corrupted raw PDF data using Visual Studio and scrolled to the end.
Here are the last 10 lines of the good file.
0000220704 00000 n 0000220739 00000 n 0000220763 00000 n 0000220848 00000 n 0000224467 00000 n trailer <> startxref 116 %%EOF
Looks pretty normal and the PDF standard is even nice enough to put an explicit EOF into the file.
And now the corrupted file...
0000220704 00000 n 0000220739 00000 n 0000220763 00000 n 0000220848 00000 n 0000224467 00000 n trailer <</Size 47>> startxref 116 %%EOF