X-Sendfile / Apache pour envoyer des gros fichiers
Posté le mardi 19 mai 2009 à 3 h 21, Read it in english with GoogleC’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
header("Content-Length: ". filesize($file));
readfile($file);
exit;
Avec le module X-Sendfile
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.