Site bloqué durant un téléchargement

C’est un problème que j’ai rencontré il y a de cela quelques temps déjà. Mais, apparemment, je ne suis pas le seul à tomber dans le « piège ».

Il est parfois nécessaire de créer un script de téléchargement pour des raisons diverses (statistiques, contrôle d’accès, etc.). Mais un problème peut subvenir en cours de téléchargement : il n’est plus possible de parcourir le site. On a l’impression que le site ne répond plus, et lorsque le téléchargement est terminé, tout se débloque.

J’ai mis du temps à résoudre le problème, mais il s’avère très simple. Tout tourne autour des sessions. En effet, comme l’indique la documentation de la fonction « session_write_close« , un verrou est mis sur les fichiers de session durant l’exécution du script, ce qui fait qu’il n’est pas possible d’avoir 2 requêtes HTTP simultanées. La seconde attendant que la première soit terminée (du moins, tant que les sessions sont encore ouvertes).

Quand le fichier à télécharger ne fait que quelques kilooctets, ce problème n’est pas visible. Par contre, dans le cas de téléchargement de gros fichiers (plusieurs mega), nous pouvons voir le blocage.

La solution est donc de libérer la session (la terminer) avant l’envoi des données. Ce qui donne par exemple :

session_start();

// code de contrôle, statistique, etc.

// envoi des en-têtes …
header('...');
header('...');
header('...');

session_write_close(); // les données de session sont écrites dans le fichier, et le verrou libéré.

readfile($fichier); // on envoi maintenant les données

Et voilà, normalement le problème disparait.