Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[php] filesize: browser ziet het niet

Pagina: 1
Acties:

Onderwerpen


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Hey Tweakers, ik ben bezig met een forced mp3 download scriptje. Werkt prima, behalve dat de browser niet ziet hoe groot het bestand is. De gebruiker heeft dus geen idee hoelang het downloaden nog gaat duren :P

Terwijl ik wel een content-length header meegeef:

PHP:
1
2
3
4
5
6
7
$file = root.'uploads/'.$fetch['filename'];

header('Content-Description: '.$fetch['original_filename']);
header('Content-type: audio/mp3');
header('Content-Disposition: attachment; filename='.$fetch['original_filename']);
header('Content-Length: '.filesize($file));
readfile($file);


Mis ik een header? Of doe ik iets anders fout?
Bvd

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

Wat is de output van die filesize-call? :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Dat is 4928734. Ik kan hem namelijk ook uit mijn database opvragen, die stored de filesize ook. Maar of ik het via die functie doe, of via de database waarde maakt niet uit :P

  • marco_balk
  • Registratie: April 2001
  • Laatst online: 20-06 21:52
Vreemd. Met jouw code krijg ik in iedere browser netjes de grootte te zien:

PHP:
1
2
3
4
5
6
7
8
9
<?php
$file = 'media/flash/promo/macaco_entrevista.flv'; 

header('Content-Description: macaco_entrevista.flv'); 
header('Content-type: audio/mp3'); 
header('Content-Disposition: attachment; filename=macaco_entrevista.flv'); 
header('Content-Length: '.filesize($file)); 
readfile($file);
?>


Wellicht is cache al gevuld door oudere code zonder die content-length?
Zie je verschil als je caching via headers uitzet?

PHP:
1
2
3
4
5
<?
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
?>

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Heb je ook de letterlijk verstuurde headers bekeken?

{signature}


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
marco_balk schreef op maandag 07 februari 2011 @ 20:41:
Vreemd. Met jouw code krijg ik in iedere browser netjes de grootte te zien:

PHP:
1
2
3
4
5
6
7
8
9
<?php
$file = 'media/flash/promo/macaco_entrevista.flv'; 

header('Content-Description: macaco_entrevista.flv'); 
header('Content-type: audio/mp3'); 
header('Content-Disposition: attachment; filename=macaco_entrevista.flv'); 
header('Content-Length: '.filesize($file)); 
readfile($file);
?>


Wellicht is cache al gevuld door oudere code zonder die content-length?
Zie je verschil als je caching via headers uitzet?

PHP:
1
2
3
4
5
<?
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
?>
hmm heb die code boven de andere headers gezet, maar heeft geen effect gehad :X

De verstuurde headers, weet iemand daar een Chrome plugin voor? :)

  • marco_balk
  • Registratie: April 2001
  • Laatst online: 20-06 21:52
Saven schreef op maandag 07 februari 2011 @ 21:03:
De verstuurde headers, weet iemand daar een Chrome plugin voor? :)
CTRL-SHIFT-i
En dan "Network" tab
Als je dan een resource kiest, kan je weer kiezen voor "headers,content,cookies en timing"

Of bedoel je dat niet?

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 10:23

voodooless

Sound is no voodoo!

ctrl-alt-J, en je kan alles :)

Check even of de transfer encoding op chunked staat in je ontvangen headers. Zoja, dan besluit de webserver blijkbaar dat hij niet weet hoe groot de response is, en stuurt doodleuk op de "geen idee hoe groot dit ding is" methode je file naar de browser.

Do diamonds shine on the dark side of the moon :?


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Hmm ik kreeg niks te zien bij de downloadrequests... Maar toen zag ik een rood kruisje rechtsonder:

Failed to load resource
xxxxxxxxxx.nl/download.php?id=56&key=956758

[ Voor 3% gewijzigd door Saven op 07-02-2011 21:41 ]


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
firefox kan het bestand btw ook niet 100% handelen als er spaties in de filename zitten :P Je krijgt dan alleen de naam voordat de eerste spatie begint. Stel:

La la land.mp3

Slaat ie dan op als
"La" zonder extentie. Like wtf?

Tevens verkapte bump ;)

  • Gamebuster
  • Registratie: Juli 2007
  • Laatst online: 23-10 08:50
Uit m'n hoofd:
PHP:
1
2
3
4
5
6
<?php
$fileSize = filesize($file);
header(sprintf('Content-Disposition: attachment; filename=%s; size=%d',
        urlrawencode($fetch['original_filename']),
        $fileSize)); 
?>


Als bovenstaande niet (goed) werkt:
PHP:
1
2
3
4
5
6
<?php
$fileSize = filesize($file);
header(sprintf('Content-Disposition: attachment; filename="%s"; size=%d',   
        addslashes($fetch['original_filename']),
        $fileSize)); 
?>


Het is me niet helemaal duidelijk welke van deze 2 de juiste methode is.

meer info:
http://php.net/manual/en/function.rawurlencode.php

Content-Length is trouwens niet de lengte van de bijlage, maar de lengte van de gehele HTTP response body. Als de HTTP response meerdere bijlages bevat, is Content-Length de grootte van alle data bij elkaar. Hierom zal de browser waarschijnlijk niet vertrouwen op Content-Length voor de grootte van het bestand; simpelweg omdat dat niet hoort. Content-Length wordt ook alleen gebruikt om te weten wanneer hij het hele HTTP response ontvangen heeft en hij de connectie eventueel kunt sluiten of een nieuw HTTP response kan ontvangen.

Lees ook:
2.3 The Filename Parameter

[...]

Current [RFC 2045] grammar restricts parameter values (and hence
Content-Disposition filenames) to US-ASCII. We recognize the great
desirability of allowing arbitrary character sets in filenames, but
it is beyond the scope of this document to define the necessary
mechanisms. We expect that the basic [RFC 1521] `value'
specification will someday be amended to allow use of non-US-ASCII
characters, at which time the same mechanism should be used in the
Content-Disposition filename parameter.
uit: http://www.ietf.org/rfc/rfc2183.txt

Content-Description is niet nodig en hoeft zeker niet de filename te bevatten:
3. Examples

Here is a an example of a body part containing a JPEG image that is
intended to be viewed by the user immediately:

Content-Type: image/jpeg
Content-Disposition: inline
Content-Description: just a small picture of me

<jpeg data>

The following body part contains a JPEG image that should be
displayed to the user only if the user requests it. If the JPEG is
written to a file, the file should be named "genome.jpg". The
recipient's user might also choose to set the last-modified date of
the stored file to date in the modification-date parameter:

Content-Type: image/jpeg
Content-Disposition: attachment; filename=genome.jpeg;
modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
Content-Description: a complete map of the human genome

<jpeg data>
uit: http://www.ietf.org/rfc/rfc2183.txt

-111 edits later-
volgens mij is-ie nu goed :P

[ Voor 215% gewijzigd door Gamebuster op 08-02-2011 14:14 ]

Let op: Mijn post bevat meningen, aannames of onwaarheden


  • Cartman!
  • Registratie: April 2000
  • Niet online
Denk niet dat t er iets mee te maken heeft maar je stuurt een flv met mimetype audio/mp3, dat lijkt me ook niet correct.

edit: nm, die flv kwam uit een code-voorbeeld van iemand anders in dit topic...

offtopic:
bump binnen 24 uur is niet de bedoeling eigenlijk

[ Voor 18% gewijzigd door Cartman! op 08-02-2011 14:13 ]


  • Marientjuh
  • Registratie: Oktober 2004
  • Laatst online: 28-11 13:16

Marientjuh

Fullstack developer

En als je eens de volledige content length weglaat?

Respect begint waar eigen kunnen ophoudt! - Kinderkleding webshop van vrouwlief: coz-adore.nl


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Cartman! schreef op dinsdag 08 februari 2011 @ 13:44:
Denk niet dat t er iets mee te maken heeft maar je stuurt een flv met mimetype audio/mp3, dat lijkt me ook niet correct.

offtopic:
bump binnen 24 uur is niet de bedoeling eigenlijk
Hm nope ik download geen flv, maar gewoon mp3 :P

ik kwam hier trouwens achter:
Content-Description: LA LA LA_NDD.mp3
Content-Disposition: attachment; filename=LA LA LA_NDD.mp3
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Keep-Alive: timeout=1, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: audio/mp3

Heeft die chunked er niet iets mee te maken? Ik ga trouwens ff de oplossing van gamebuster proberen

  • Gamebuster
  • Registratie: Juli 2007
  • Laatst online: 23-10 08:50
Transfer-Encoding: Chunked maakt niet echt uit; dat komt waarschijnlijk omdat je gzip compressie gebruikt. Het gebruik van chunked transfer encoding maakt de content-length header overbodig en wordt daarom weggehaald.

Zie ook: Wikipedia: Chunked transfer encoding

Zolang je maar filesize meestuurt zoals in bovenstaande voorbeeld van mij; dat zou moeten werken, al heb ik het niet getest.

[ Voor 44% gewijzigd door Gamebuster op 08-02-2011 14:11 ]

Let op: Mijn post bevat meningen, aannames of onwaarheden


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Hmm, ik krijg die filesize nog steeds niet aan de praat. Inmiddels heb ik deze headers:

PHP:
1
2
3
4
5
6
7
8
9
10
11
$fsize = filesize($file);

header("Pragma: public"); // required 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Cache-Control: private",false); // required for certain browsers 
header("Content-Type: application/force-download"); 
header("Content-Disposition: attachment; filename=\"".$fetch['original_filename']."\"; size=".$fsize.";"); 
header("Content-Transfer-Encoding: binary"); 

readfile( $file );

Ergens van php.net afgeplukt. Nu gaat het met de filename gewoon goed in firefox en chrome met spaties. IE zet er _ (underscores) tussen ipv spaties :)

Alleen die filegrootte lukt nog steeds niet |:(

[ Voor 4% gewijzigd door Saven op 08-02-2011 14:25 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 27-11 13:05

Janoz

Moderator Devschuur®

!litemod

Gamebuster schreef op dinsdag 08 februari 2011 @ 14:09:
Transfer-Encoding: Chunked maakt niet echt uit; dat komt waarschijnlijk omdat je gzip compressie gebruikt.
Chunked maakt wel degelijk uit en is waarschijnlijk exact de reden waarom het hier niet goed gaat. Chuncked wordt gebruikt wanneer van te voren niet duidelijk is hoe lang het response gaat worden en bij chuncked wordt de filesize header dus compleet verwijderd. Deze aanpassing wordt waarschijnlijk door de webserver gedaan.

[ Voor 24% gewijzigd door Janoz op 08-02-2011 14:43 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Hm dus toch :P Maar hoe los je dat in hemelsnaam op, want filesize meegeven heeft dus geen nut blijkbaar

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 27-11 13:05

Janoz

Moderator Devschuur®

!litemod

Ergens is gzip ingesteld. Waarschijnlijk in de webserver. Die pakt je response, sloopt de content-length header eruit en zet er de chuncked en gzip header in. Die zul je op 1 of andere manier uit moeten zetten voor dit request.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Saven
  • Registratie: December 2006
  • Laatst online: 10:08

Saven

Administrator

Topicstarter
Problem bijna fixt :) Thanks Janoz voor de tip.

Oplossing:

.htaccess
code:
1
SetEnvIfNoCase Request_URI download\.php$ no-gzip dont-vary


php headers:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$file = root.'uploads/'.$fetch['filename'];

header("Pragma: public");
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Cache-Control: private", false);
header("Content-Type: application/force-download"); 
header("Content-Disposition: attachment; filename=\"".$fetch['original_filename']."\"; size=".$fetch['filesize'].";");
header('Content-Length: '.$fetch['filesize']);
header("Content-Transfer-Encoding: binary"); 

readfile( $file );


Alleen IE (ie8) ziet nog geen filesize 8)7

[ Voor 13% gewijzigd door Saven op 08-02-2011 15:14 ]


  • jmxd
  • Registratie: September 2005
  • Niet online
moet je die size= wel meegeven in die header? :P

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Ik denk dat dit linkje je ook wel kan helpen :)
http://w-shadow.com/blog/...e-file-download-with-php/

Kijk dan ook eens naar de volgende headers:
PHP:
1
2
 header("Content-Transfer-Encoding: binary");
 header('Accept-Ranges: bytes');

edit: Ik zie dat je de bovenste al geprobeerd hebt. Misschien in combinatie met die eronder ? Of zou dat zijn voor hervatbare downloads?

[ Voor 20% gewijzigd door Aloys op 08-02-2011 21:58 ]


  • FastPinguin
  • Registratie: Oktober 2009
  • Laatst online: 18-10 00:53
Als je dit in je .htaccess file zet wordt mp3 geforceerd als download:

AddType application/octet-stream .mp3

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Waarom ben je het wiel opnieuw aan het uitvinden en ga je dit handmatig met PHP doen? Webservers zijn hiervoor geoptimaliseerd en kunnen dit _heel_ goed en je weet dat het getest is in de meeste browsers.

Gebruik gewoon X-Sendfile om je webserver het bestand te laten versturen en klaar ben je:
Apache: https://tn123.org/mod_xsendfile/
Nginx: http://wiki.nginx.org/XSendfile

Blog [Stackoverflow] [LinkedIn]

Pagina: 1