PDF Download Problem

Hi Guys!

I have created a script which uploads PDF’s into a database and stored as a blob. I have also created a download script to download the PDF. Both scripts work fine on my site from admin (mysitecom/cms). I am using exactly the same download function from the user side (wordpress site), however I get an error in my browser when I try and download the PDF from the user side. The error is the same in Firefox, IE and Safari.

The error says:


The file “Kirk-7.pdf” could not be opened.

It may be damaged or use a file format that Preview doesn’t recognize.

Here is my PHP download script:


function DownloadPDF(){
		$result = $this->dbh->getRow("select * from pdfs where id='".mysql_real_escape_string($_GET['pdfid'])."'", DB_FETCHMODE_ASSOC);
		
		if(!empty($result['id'])){
			header("Content-length: ".$result['pdf_size']);
			header("Content-type: application/pdf");
			header('Content-Disposition: attachment; filename="'.$result['pdf_name'].'"');
			echo $result['pdf_content'];
		} else {
			$Error['error'] = "You do not have any PDF's available to download.";
			return $Error;
		}
	}

Am I missing something?

Thanks.

Hi Guys,

I done a print_r() on the $result and it seems the pdf content is getting cut off (i.e. the data is missing which is why we are getting a corrupted error.

Any idea why this would happen?

Does the full content exist in the database?

Yes the full content exists in the database (100%).

Does $result[‘pdf_size’] equal strlen($result[‘pdf_content’]) ?

Maybe the pdf_size is smaller than the actual size of the pdf’s content, causing the browser to close the connection after downloading pdf_size data.

Yes both of the sizes correlate to each other - 44838. Could it be something to do with the charset?

Hmm, it could be, actually.

If the file is multibyte, then strlen might return an incorrect value.
Try using [fphp]mb_strlen[/fphp].

Something else you could try, just to find out what’s going on, is to write a script that will write out the PDF file on disk somewhere, download that file through FTP/ SSH/ whatever and see how large it is, and then compare that to the files you’ve downloaded through the web interface.

Ahhhaaaa…now when I do mb_strlen($result[‘pdf_content’]) I get 32281 as opposed to the value I posted yesterday.

What does this mean?

Not sure actually :slight_smile:
Sorry, that’s not very helpful, is it.

What happens if you try to download the file without sending a Content-Length header?
(I know, it’s bad practice, but it’s just to see what’s going on so we can figure out what the actual content length is).

Off Topic:

Lovin’ the thought processes Immerse! :wink:

strlen() should return the binary length of whatever data is input. In general, I don’t output a ‘Content-Length’ header because it isn’t recommended - try removing that. You should check your file and make sure that you don’t have a Unicode header being prepended by your editor when you save and also make sure that there are no extra characters being output (e.g. even a single whitespace character after the ‘?>’ can do weird stuff). Might also want to check that the data being output is actually a PDF (e.g. no errors/warnings or other bad data) by dropping the other two header() statements to test that possibility.

Off Topic:

Yeah, sometimes my thoughts are actually organised properly, usually they just pop in and out of my as I post them :wink:

I tried downloading without a Content-Length but get the same error.

It’s so strange, the exact same function works fine from admin, but in the client area (which is run by Wordpress) the pdf_content field is cut off. Would there be anything inside wordpress that could cause this?

Here is the PDF content from admin (this works):

%PDF-1.3 %âãÏÓ 3 0 obj &lt;&lt; /Linearized 1 /O 5 /H [ 797 164 ] /L 6365 /E 5955 /N 1 /T 6188 &gt;&gt; endobj xref 3 20 0000000016 00000 n 0000000744 00000 n 0000000961 00000 n 0000001112 00000 n 0000001291 00000 n 0000001835 00000 n 0000002215 00000 n 0000002402 00000 n 0000002593 00000 n 0000002773 00000 n 0000004378 00000 n 0000004488 00000 n 0000004770 00000 n 0000004839 00000 n 0000005020 00000 n 0000005195 00000 n 0000005401 00000 n 0000005813 00000 n 0000000797 00000 n 0000000941 00000 n trailer &lt;&lt; /Size 23 /Info 2 0 R /Root 4 0 R /Prev 6179 /ID[&lt;4dc91a1875a6d707aec203bb021c93a0&gt;&lt;4dc91a1875a6d707aec203bb021c93a0&gt;] &gt;&gt; startxref 0 %%EOF 4 0 obj &lt;&lt; /Type /Catalog /Pages 1 0 R &gt;&gt; endobj 21 0 obj &lt;&lt; /S 36 /Filter /FlateDecode /Length 22 0 R &gt;&gt; stream H‰b``b``–ea'l€J aWn.Ço'¼‘k®c`Ua`g¸¢äµƒ“ À¨â’ endstream endobj 22 0 obj 60 endobj 5 0 obj << /Type /Page /Parent 1 0 R /Resources 6 0 R /Contents 12 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 6 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 13 0 R /TT2 8 0 R /TT4 7 0 R /TT6 17 0 R /TT8 19 0 R >> /ExtGState << /GS1 20 0 R >> /ColorSpace << /Cs5 11 0 R >> >> endobj 7 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 174 /Widths [ 250 0 0 0 0 0 0 180 333 333 0 0 250 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 667 722 0 556 0 0 0 0 0 0 0 0 0 556 0 667 0 611 0 0 944 0 0 0 0 0 0 0 0 0 444 500 444 500 444 333 500 500 278 0 0 278 778 500 500 500 0 333 389 278 500 500 722 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 760 ] /Encoding /WinAnsiEncoding /BaseFont /TimesNewRomanPSMT /FontDescriptor 10 0 R >> endobj 8 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 116 /Widths [ 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 722 0 611 0 0 0 0 0 0 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 611 556 611 556 0 0 0 278 0 0 278 0 0 611 0 0 389 556 333 ] /Encoding /WinAnsiEncoding /BaseFont /Arial-BoldMT /FontDescriptor 9 0 R >> endobj 9 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -628 -376 2034 1048 ] /FontName /Arial-BoldMT /ItalicAngle 0 /StemV 133 >> endobj 10 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 34 /FontBBox [ -568 -307 2028 1007 ] /FontName /TimesNewRomanPSMT /ItalicAngle 0 /StemV 0 >> endobj 11 0 obj [ /CalRGB << /WhitePoint [ 0.9505 1 1.089 ] /Gamma [ 2.22221 2.22221 2.22221 ] /Matrix [ 0.4124 0.2126 0.0193 0.3576 0.71519 0.1192 0.1805 0.0722 0.9505 ] >> ] endobj 12 0 obj << /Length 1530 /Filter /FlateDecode >> stream H‰´WKoã6F¯þs[ªˆ½Çt·)ÐÓb+ ‡n²Ä$*dÑé¤ùSýai{- ,ZPøræ›™oÆ?t›Û®Ë …îa“qR@‚2ÊÒ<®«¤‚º¬qžäÐí7·ïm	ƒåc	ØasûÓ/)<ÚÍ6‰“$« e64ªè^6¿©»(MâLÑ¶ŽSev¢mJCÜhâZ Ñ6Sk´ â w{a?ÜÃýDšµ~ï~&¯c& fдq›‘rYeç™(Ç:$ ×!£ë0â»ÁG³º~7kø`P‡$nÕpÜëÅÁ}TƹÂEZ[÷¸™£‚¨Ëg…Úðæç&Kª'ª‡ã2=ëÕö³,!¢³9Š´å-^Fx”U™ž&‘±Q¢ÀȽ^Q/Á—½ÊSb²Å›EÊ[1™IQÒT_ˆºeu´-qÏkÝÓ,÷Ž¢±ˆYˆaÚ}‘I#„þp˜§¡w“Y GÃsïȉp´¬F¦ôÎÀ°j	Ñß*”Ó0¹8ø,‹sï²”ÂðqŒ™P+ØNÇEf#_Zò¥¥šÅsB¢hèÙeø˜[Í2 „C•áÅð8Y·N»£˜bQ?0¤ƒÙk+W& Ô'PjQü°̐½Ü›eæZòf™½°Z˜¶æ¸8́]F/“{"MaVÏK À©aŸz2Sƒ>WÓòÑe‚ßí½g²a$Y+RH}uPúWþP\\T˜þx•ÆƒpWHÒeVµ%ßs·¼šEß “__ž4zS„=« ^˜aI½p (0 ÇÌA#°HOѶÁ@#¯fŠ Œán&*ÈÆI™£Äø¢	!ža¡Àâ@ü0¦ýŒb†‚N…ù°ú…qÃ$`¼¶¬+¹±Ʀ>´Ó¤©DáOšµëù;F’N4^1; s¤}Ò¯MÄ{:LrdáãN"“ˆdLQt¾Äó O ß §ör¹hâdbÁbTÊÊäap*/„q¥ÞE˜‚UCÈò¥žð¥vúò¢#²^=2`‹µ¸è«éð†#F³¼Ã`Eðá©î&(‰àÌž(õ,2Ç?Q	œÓ¶¢´µWI€ú”ߘaÅ×ò@Bce†dRMŒ{\\¨´>¡°(/.*Ï•rQ?¿ô¯\\‘ø‘à°NHDƒ/¦h‰ZWÍ3YsóëU5ÇDj/ò.ÉNøû‚aÌËT[QE&¡Æ¿3	QãÅQ?‹#Ä?õ5½ß‹â¿Ä6ôiݦ—ЦmŽt7q1ªÚžÿ™"/Ȇ)áñeÔ z(ƒŽÕçË kŸPëð–åäq.µú³Þâœ]á4oC‡DƒI‡£–lè¹Aqz¤Ò+í‹lÞa{gß,ù~†Ê.Ö.îC¬ypd+	 L½£0 4ù™Â¾L½*¤òíÚa7ü¬ov°4giˆa¬õë•P‘òeeD%]Ùl¨Y	Íg'Õ¤JI ^ŒƒÙX,¦GM)º³-,¶HÛæ ºjÛÒìœ*>ŒŸ1 ˜3ö6fÆõ´`Zp¢dj@¾B6ÜMó䈈ÕÿÉÛ³š¾AËùéAüIwƒŒVnË?é~-ÑJ½°?×3~äv•F‚n4/Ëlú‘»*‰,¬¡»Sá¯`üdDAôÔÆ ‰î.Yú*ysõDOtA…ºaÛD³°ª±%ýw ¿™]s°hß>½7ìIŒø¿N~Sœ:ÁIñT8sO¾é©½¦ñ*y,e`÷²:û“+Ëa)‘e*‚<¥Ê„&ÿCFŽR§Í£Á_yý´¿iô>“›dÝ÷U„ˆá¨}¤pŽ_D]F …]c¯4üK¤]heÝíéQxçs«¡àWúîā?v›¿a ‡Ý endstream endobj 13 0 obj << /Type /Font /Subtype /Type1 /Encoding 15 0 R /BaseFont /Symbol /ToUnicode 14 0 R >> endobj 14 0 obj << /Filter /FlateDecode /Length 208 >> stream H‰T½Â0„÷>…GCÚÎUX:ð# ìiâV‘ˆ¹éз')ÄKöåӝ-öÍ¡!@\\Ø©ô†4ãè&V† (AeÖn©ÊJ"Âí<´ õª*×(ŽgØ´³íÜs—oAœY#e`s+î8h'ïŸh‘äP× ±ÏÄþ(ýIZŒòŠ.ób5tG/²¤¡Ê‹ú]ô¿ö!ºþÝþ¾Ve^–u‰–à´É×[MÌ1Ö²î’(e0„ß‹xç“ezÙK€CÈi? endstream endobj 15 0 obj << /Type /Encoding /Differences [ 1 /bullet ] >> endobj 16 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -665 -325 2028 1037 ] /FontName /ArialMT /ItalicAngle 0 /StemV 0 >> endobj 17 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 32 /Widths [ 278 ] /Encoding /WinAnsiEncoding /BaseFont /ArialMT /FontDescriptor 16 0 R >> endobj 18 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 98 /FontBBox [ -547 -307 1206 1032 ] /FontName /TimesNewRomanPS-BoldItalicMT /ItalicAngle -15 /StemV 133 >> endobj 19 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 444 0 444 0 0 556 278 0 0 278 0 556 500 500 0 389 389 278 0 0 667 500 444 ] /Encoding /WinAnsiEncoding /BaseFont /TimesNewRomanPS-BoldItalicMT /FontDescriptor 18 0 R >> endobj 20 0 obj << /Type /ExtGState /SA false /SM 0.02 /TR /Identity >> endobj 1 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 2 0 obj << /ModDate (D:20000629102135+11'00') /CreationDate (D:20000629102108+11'00') /Title (This is a test PDF file) /Author (cdaily) /Creator (Microsoft Word 8.0) /Producer (Acrobat Distiller 4.0 for Windows) >> endobj xref 0 3 0000000000 65535 f 0000005891 00000 n 0000005955 00000 n trailer << /Size 3 /ID[<4dc91a1875a6d707aec203bb021c93a0><4dc91a1875a6d707aec203bb021c93a0>] >> startxref 173 %%EOF

Here is the PDF content from client area (corrupt download):


%PDF-1.3 %&#65533;&#65533;&#65533;&#65533; 3 0 obj << /Linearized 1 /O 5 /H [ 797 164 ] /L 6365 /E 5955 /N 1 /T 6188 >> endobj xref 3 20 0000000016 00000 n 0000000744 00000 n 0000000961 00000 n 0000001112 00000 n 0000001291 00000 n 0000001835 00000 n 0000002215 00000 n 0000002402 00000 n 0000002593 00000 n 0000002773 00000 n 0000004378 00000 n 0000004488 00000 n 0000004770 00000 n 0000004839 00000 n 0000005020 00000 n 0000005195 00000 n 0000005401 00000 n 0000005813 00000 n 0000000797 00000 n 0000000941 00000 n trailer << /Size 23 /Info 2 0 R /Root 4 0 R /Prev 6179 /ID[<4dc91a1875a6d707aec203bb021c93a0><4dc91a1875a6d707aec203bb021c93a0>] >> startxref 0 %%EOF 4 0 obj << /Type /Catalog /Pages 1 0 R >> endobj 21 0 obj << /S 36 /Filter /FlateDecode /Length 22 0 R >> stream H&#65533;b``b``&#65533;e

Compare the headers sent using something like LiveHTTPHeaders.

Here are the results from the LiveHTTPHeaders, response headers only.

Admin (download OK):


HTTP/1.1 200 OK
Date: Mon, 06 Dec 2010 11:02:15 GMT
Server: Apache
X-Powered-By: PHP/5.2.14
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 3488
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Content-Type: text/html

Client area (download error):


HTTP/1.1 200 OK
Date: Mon, 06 Dec 2010 11:01:19 GMT
Server: Apache
X-Powered-By: PHP/5.2.14
X-Pingback: http://www.hiddenurl.com/xmlrpc.php
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 392
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

You have no charset in the admin side…

Can you compare the headers when downloading a PDF?

How can I compare the headers when downloading a PDF? The outputs posted above are just from the page which does a print_r of the pdf content.

Exactly the same way, just do whatever you do to download a PDF and paste the headers here.

When I download a PDF a dialog box just pops up and I am asked to save or open the file. Im not sure how to check the headers on this dialog box…