28th August, 2009
I’ve been rather busy lately producing the PHP backend code for a document storage website and when it came to the question of where to actually store the files the answer naturally was somewhere outside of public_html so that control could be limited using the user authentication already available for the PHP pages. This meant that PHP would have to deliver a response as if the actual file itself was being accessed.
It’s pretty easy to find how to send alternative headers and a the source data from a PDF file: for example http://uk3.php.net/manual/en/function.header.php Additionally, there is plenty of information out there if you want to use ‘Content-Disposition’ to force the client’s browser to behave as if the file was a download rather than load Adobe Reader in the window itself.
However this was all fine until we discovered that Adobe Reader’s usual behaviour of displaying the first page and loading the document as it is being read was broken. This system is intended for some fairly large documents and the browser was choosing to download and cache the entire file before displaying anything. I knew immediately it would be something to do with the headers.
There is very little I could find that expanded on this issue, so using an online tool that can be found at http://www.askapache.com/online-tools/http-headers-tool/ I examined what response would be sent by accessing a PDF file directly from the server. Using this I could replicate the header in PHP and as I guessed, the issue was resolved:
header('Accept-Ranges: bytes');
header('Content-Length: '.$filesize);
header('Connection: close');
header('Content-Type: application/pdf');