X-Sendfile / Apache pour envoyer des gros fichiers

Posté le Mardi 19 mai 2009 à 3 h 21, Read it in english with Google

C’est un fait, les langages interpr√©t√©s comme PHP, Ruby ou Perl sont moins rapide que les langages compil√©s (comme C, C++..) ou m√™me semi-interpr√©t√©s (comme Java). Outre cela, dans n’importe quel serveur web qui utilise des programmes externes √† lui m√™me pour rendre un contenu, il y a des pertes du √† la communication entre ces programmes. Dans le cas de l’envoie de gros fichiers par PHP, les pertes deviennent non n√©gligeable, il y a encore plus de donn√©es √† communiquer √† Apache qui sert ici d’interm√©diaire, on peut donc remarquer qu’il est plus long de t√©l√©charger un fichier envoy√© via PHP qu’un fichier directement rendu par Apache (apr√®s bien sur √ßa d√©pends de la charge de votre serveur).

Le module Apache X-Sendfile permet de dire √† Apache quel fichier envoyer, apr√®s l’ex√©cution d’un script (PHP par exemple). Vous pourrez ainsi ex√©cuter tranquillement votre script PHP, et si un fichier doit √™tre envoy√©, vous le direz √† Apache qui s’en chargera. Durant toutes la dur√©e du transfert c’est Apache qui g√®rera les donn√©es et non plus le couple Apache + PHP. On gagne ainsi en temps processeur, en m√©moire, et en gestion puisque Apache prend en compte des ent√™tes qu’il n’est pas √©vident de traiter.

Un petit exemple pour vous mettre l’eau √† la bouche :

Sans le module X-Sendfile

<?php
$file = 'send-file.gz';
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename="" . basename($file) . '"');
header("Content-Length: ". filesize($file));
readfile($file);
exit;

Avec le module X-Sendfile

<?php
$file = 'send-file.gz';
header('X-Sendfile: '.$file);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachement; filename="'.basename($file).'"');
exit;

Installation

Cette fonctionnalit√© est disponible par d√©faut dans lighttpd. Pour ce qui est d’Apache, le module n’est pas officiel.

Vous pouvez utiliser le paquet .deb qui marche très bien pour Apache 2.2 ou bien télécharger et compiler les sources avec apxs2 :
aptitude update
aptitude install apxs2
wget http://tn123.ath.cx/mod_xsendfile/mod_xsendfile.c
apxs2 -i -a -c mod_xsendfile.c
echo "LoadModule xsendfile_module /urs/lib/apache2/modules/mod_xsendfile.so" > /etc/apache2/mods-available/xsendfile.load
a2enmod xsendfile
/etc/init.d/apache2 restart

N’oubliez pas d’activer le module dans un htaccess :
XSendFile On
XSendFileAllowAbove on

XSendFileAllowAbove est une option de s√©curit√© emp√™chant apparemment au module d’aller chercher un fichier en dessous du fichier de script courant.

Une solution comparable et plus professionnel serait d’utiliser le Zend Download Server qui r√©pond √† la m√™me probl√©matique.

Laissez un commentaire :