Ik zit met een leuk probleem, en ik kom er niet meer uit. Ik heb een extranet gebouwd, waarbij werknemers van all over the world in kunnen loggen op een intranet-achtige omgeving. Hier vindt men nieuwsberichten, is een forum etcetera. Tevens kan men daar allerlei bestanden downloaden (handleidingen, templates, urenstaten, etc).
Je moet echter wel ingelogd zijn om zo'n file te kunnen downloaden, en dus moet de download van zo'n file via een scriptje lopen dat checkt of er een actieve session is met een geldige username & password. De link naar de file wordt dan iets als download.php?id=169.
Ook dat is geen probleem; met onderstaande code forceer ik een download van de betreffende file:
Nu zijn ze bij dat bedrijf echter bezig met zich te conformeren aan een ISO-normering, en een van de regels waar men aan moet voldoen, is dat files op één centrale plaats opgeslagen moeten worden, zodat iedereen die kan gebruiken. Oftewel, een PDF moet niet gedownload worden, maar moet geopend worden in de browser.
Dat betekent dus dat ik in mijn scriptje onderscheid moet maken tussen de verschillende soorten files (ik check bij het uploaden op mimetype en sla dat op in een database) en of ze in de browser te openen zijn of niet. PDF's, DOC's, XSL's, JPEG's en GIF's zijn allemaal in de browser te openen. Maar dat zijn niet de enige files die men daar opslaat, men heeft ook EPS'en, DOT's, PSD's en meer van dat soort ongein.
Je ontkomt er dus niet aan dat sommige files wel gedownload moeten worden, in plaats van in de browser geopend.
In ieder geval, ik ga dus een check doen op mimetype om te kijken of de file in de browser weergegeven kan worden of niet, en zo ja dan geef ik in plaats van application/octet-stream bijvoorbeeld application/pdf mee.
Ik ging dit testen, en het werkte prima. Maar niet bij iedereen. Lang niet bij iedereen zelfs. Men kreeg toch een download dialog bij een PDF, waarna er een error gegeven werd. Of Acrobat Reader werd geladen, maar er verscheen geen PDF in de browser. Enzovoorts.
En nu weet ik dus niet meer waar ik het zoeken moet; ik heb op aanraden van kees eens wat headers vergeleken van een normale PDF en een PDF die via mijn scriptje wordt gedownload:
Headers van een 'normale' PDF (i.e. http://blaat/file.pdf) :
De zaken die wel in mijn scriptje staan maar niet bij een gewone PDF terugkomen: de Expire/Cache-headers, en de X-Powered-By en de Set-Cookie headers.
Waar komt het nu op neer? Ik weet het niet meer
Ik ben uren aan het klooien geweest en kom er niet meer uit. Ik zoek dus naar een oplossing waarbij 'bekende' files in de browser geopend worden, en overige files een download dialog genereren. Wie helpt me uit de brand?
Je moet echter wel ingelogd zijn om zo'n file te kunnen downloaden, en dus moet de download van zo'n file via een scriptje lopen dat checkt of er een actieve session is met een geldige username & password. De link naar de file wordt dan iets als download.php?id=169.
Ook dat is geen probleem; met onderstaande code forceer ik een download van de betreffende file:
PHP:
1
2
3
4
5
| if ($fp = @fopen($savepath["documents"] . $rFilename, "r")) { header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=" . $rFilename); @fpassthru($fp); } |
Nu zijn ze bij dat bedrijf echter bezig met zich te conformeren aan een ISO-normering, en een van de regels waar men aan moet voldoen, is dat files op één centrale plaats opgeslagen moeten worden, zodat iedereen die kan gebruiken. Oftewel, een PDF moet niet gedownload worden, maar moet geopend worden in de browser.
Dat betekent dus dat ik in mijn scriptje onderscheid moet maken tussen de verschillende soorten files (ik check bij het uploaden op mimetype en sla dat op in een database) en of ze in de browser te openen zijn of niet. PDF's, DOC's, XSL's, JPEG's en GIF's zijn allemaal in de browser te openen. Maar dat zijn niet de enige files die men daar opslaat, men heeft ook EPS'en, DOT's, PSD's en meer van dat soort ongein.
Je ontkomt er dus niet aan dat sommige files wel gedownload moeten worden, in plaats van in de browser geopend.
In ieder geval, ik ga dus een check doen op mimetype om te kijken of de file in de browser weergegeven kan worden of niet, en zo ja dan geef ik in plaats van application/octet-stream bijvoorbeeld application/pdf mee.
PHP:
1
2
3
4
5
6
7
8
9
10
| // browserMimetypes is dus een array waarin de mimetypes van PDF, DOC etc staan if ($fp = @fopen($savepath["documents"] . $rFilename, "r")) { if (!in_array($rMimeType, $browserMimetypes)) { header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=" . $rFilename); } else { header("Content-Type: " . $rMimeType); } @fpassthru($fp); } |
Ik ging dit testen, en het werkte prima. Maar niet bij iedereen. Lang niet bij iedereen zelfs. Men kreeg toch een download dialog bij een PDF, waarna er een error gegeven werd. Of Acrobat Reader werd geladen, maar er verscheen geen PDF in de browser. Enzovoorts.
En nu weet ik dus niet meer waar ik het zoeken moet; ik heb op aanraden van kees eens wat headers vergeleken van een normale PDF en een PDF die via mijn scriptje wordt gedownload:
Headers van een 'normale' PDF (i.e. http://blaat/file.pdf) :
Headers van een pdf via mijn script (i.e. http://blaat/download.php?id=169) :HTTP/1.1 200 OK
Date: Mon, 10 Feb 2003 16:03:13 GMT
Server: Apache/2.0.40 (Red Hat Linux)
Last-Modified: Fri, 28 Jun 2002 13:21:48 GMT
ETag: "8e4da-87eb-646d9300"
Accept-Ranges: bytes
Content-Length: 34795
Connection: close
Content-Type: application/pdf
Wat valt hierin op? In de eerste headers wordt melding gemaakt van Last-Modified, maar ik verwacht niet dat dat boeiend is. Ten tweede is er een ETag-header, en die zie ik ook niet terug bij mijn scriptje. Tenslotte is er de Content-Length. Omdat ik dacht dat het hier misschien aan zou kunnen liggen, heb ik die ook aan mijn script meegegeven, maar die header werd simpelweg NIET teruggegeven door de webserver...Date: Wed, 12 Feb 2003 11:00:02 GMT
Server: Apache/2.0.40 (Red Hat Linux)
Accept-Ranges: bytes
X-Powered-By: PHP/4.2.2
Set-Cookie: PHPSESSID=ed25289b13be3e334584eb1b610b6b71; path=/
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
Connection: close
Content-Type: application/pdf
De zaken die wel in mijn scriptje staan maar niet bij een gewone PDF terugkomen: de Expire/Cache-headers, en de X-Powered-By en de Set-Cookie headers.
Waar komt het nu op neer? Ik weet het niet meer