2010-04-11 3 views
2

Ce message a commencé comme une question sur ServerFault (https://serverfault.com/questions/131156/user-receiving-partial-downloads) mais j'ai déterminé que notre script PHP était le coupable. Donc, je publie une question mise à jour ici sur ce que je crois être le problème réel. J'utilise un script php pour vérifier les permissions et ensuite mettre à disposition un fichier pour les utilisateurs de mon site web à télécharger. La plupart du temps, cela fonctionne, mais récemment un utilisateur a vu des problèmes avec des téléchargements plus importants. Il n'obtient que ~ 80% de téléchargements pour les fichiers de plus de 100 Mo. En outre, tous les téléchargements de ce script ne parviennent pas à signaler une taille de fichier. En outre, les tests ont révélé que le même utilisateur pouvait télécharger de manière fiable chacun des fichiers en échec si un lien direct lui était donné (à quel moment la taille du fichier est indiquée).Script de traitement de fichiers PHP: Téléchargements non fiables?

Voici l'extrait pertinent du code que nous utilisons pour servir le fichier:

header("Content-type:$contenttype"); 
$len = filesize($filename); 
header("Content-Length: $len"); 
header("Content-Disposition: attachment; filename=".$title.".".$ext); 
readfile($filename); 

Notez que ContentType $, $ filename, $ title et ext $ sont tous réglés correctement avant d'arriver ici. Ceux-ci ont été triés. Aucun d'eux n'est le problème. En outre, $ len fournit la taille de fichier correcte.

Bien que des recherches de cette question, je suis tombé sur ce poste: Content-Length header always zero

Il semble que je rencontre le même problème. Lorsque j'utilise le script, je reçois un codage en morceaux sur le fichier et aucune taille n'est définie pour la longueur du contenu. Je fais l'hypothèse que quelque chose ne va pas sur les gros téléchargements, ce qui l'amène à obtenir un morceau de longueur nulle avant la fin du fichier.

Voici ce que les en-têtes ressemblent à une demande directe:

http://www.grinderschool.com/videos/zfff5061b65ae00e8b21/KillsAids021.wmv 

GET /videos/zfff5061b65ae00e8b21/KillsAids021.wmv HTTP/1.1 
Host: www.grinderschool.com 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 115 
Connection: keep-alive 
Referer: http://www.grinderschool.com/phpBB3/viewtopic.php?f=14&p=29468 
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884 
Pragma: no-cache 
Cache-Control: no-cache 

HTTP/1.1 200 OK 
Date: Sun, 11 Apr 2010 12:57:41 GMT 
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635 
Last-Modified: Sun, 04 Apr 2010 12:51:06 GMT 
Etag: "eb42d6-7d9b843-48368aa6dc280" 
Accept-Ranges: bytes 
Content-Length: 131708995 
Keep-Alive: timeout=10, max=30 
Connection: Keep-Alive 
Content-Type: video/x-ms-wmv 

Et voici ce qu'ils ressemblent à la demande une réponse par mon script:

http://www.grinderschool.com/download_video_test.php?t=KillsAids021&format=wmv 

GET /download_video_test.php?t=KillsAids021&format=wmv HTTP/1.1 
Host: www.grinderschool.com 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729) 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 115 
Connection: keep-alive 
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884 

HTTP/1.1 200 OK 
Date: Sun, 11 Apr 2010 12:58:02 GMT 
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635 
X-Powered-By: PHP/5.2.11 
Content-Disposition: attachment; filename=KillsAids021.wmv 
Vary: Accept-Encoding 
Content-Encoding: gzip 
Keep-Alive: timeout=10, max=30 
Connection: Keep-Alive 
Transfer-Encoding: chunked 
Content-Type: video/x-ms-wmv 

La question est ... Que puis-je faire pour que les téléchargements du script fonctionnent correctement? Encore une fois, pour 99% des utilisateurs, cela fonctionne tel quel (bien que je trouve cela ennuyeux maintenant qu'aucune taille de fichier n'est rapportée et donc qu'aucune estimation de temps ne peut être calculée au sujet du téléchargement).

Répondre

2

C'est votre compression GZIP. Lorsque vous spécifiez une longueur de contenu mais que vous activez la compression, cela gomme tout. Cela m'est arrivé plusieurs fois: essayez de l'éteindre dans votre script.

En général, vous souhaitez allumer avec:

ob_start("ob_gzhandler"); 

... seulement en commentaire de cette ligne sur. Si ce n'est pas dans votre code, il y a de fortes chances qu'il y ait un paramètre dans votre fichier php.ini quelque part ou dans votre fichier apache.conf/conf.d.

Espérons que cela aide!

+0

Cette ligne n'est nulle part dans le code, donc je suis en train de creuser php.ini. Si vous savez ce que je devrais rechercher, ce serait très utile! –

+0

Essayez de chercher ceci: 'zlib_output_compression'. Il devrait être réglé sur Off. – mattbasta

+0

Mon mauvais: 'zlib.output_compression = Off' et' zlib.output_handler = Off' – mattbasta

2
Content-Encoding: gzip 

Hmm. On peut supposer que c'est ce que fait zlib.output_compression de PHP. (Ne ressemble pas à mod_deflate d'Apache.)

Essayez de l'éteindre et de voir si c'est ce qui force l'encodage en segments. Vous ne voulez pas compresser le téléchargement d'un type de fichier comme WMV qui est déjà fortement compressé. Cependant, le codage en segments ne peut qu'expliquer le manque de rapport de taille. Le téléchargement devrait toujours fonctionner. Est-il possible que vous soyez touché par un dépassement de délai (par exemple, set_time_limit de PHP, ou Apache Timeout)?

+0

Je suis d'accord que les deux sont probablement liés. J'essaie de régler la cause. zlib.output_compression est déjà défini sur Off dans php.ini –

0

Si c'est le script, alors avez-vous essayé d'utiliser une fonction de remplacement pour la fonction readfile() qui lit et sort un bit à la fois? Le raisonnement derrière ceci pourrait être qu'une limite de mémoire soit atteinte quelque part et qu'elle échoue.

De http://php.net/manual/en/function.readfile.php:

function readfile_chunked ($filename) { 
    $chunksize = 1*(1024*1024); // how many bytes per chunk 
    $buffer = ''; 
    $handle = fopen($filename, 'rb'); 
    if ($handle === false) { 
    return false; 
    } 
    while (!feof($handle)) { 
    $buffer = fread($handle, $chunksize); 
    print $buffer; 
    } 
    return fclose($handle); 
} 

Aussi, essayez de vider la sortie aussi souvent que vous le pouvez.

Questions connexes