OVH + FastCGI + DEFLATE = Content-Length erroné

Hey OVH, Content-Length est erroné lorsque la compression GZIP est activée avec FastCGI, alors c'est peut-être pas une bonne idée de l'activer par défaut sur tous vos serveurs. Mattias Geniar en parle dans son article Apache’s mod_fastcgi and mod_deflate troubles et fournit quelques solutions.

La preuve par trois

J'avais déjà une idée du problème lorsque je voyais que Firefox passait plus de 5 secondes à recevoir des données alors que j'ai une connexion 50mb. « Décidément, il doit attendre des données qui ne viennent jamais, jusqu'à ce que le timeout de déclenche ».

C'est en comparant les headers de différentes configurations que mes soupçons furent confirmés, il y a bien un problème avec le champ Content-Length.

Voici les headers de trois différentes configurations, et leurs effets.

Fast-CGI sans DEFLATE

Il ne s'agit pas du mode par défaut d'OVH. Pour l'activer il faut ajouter la directive SetEnv no-gzip 1 à votre « .htaccess ». Avec cette configuration Content-Length vaut 12311 et l'évènement on load se déclenche à 433ms.

HTTP/1.1 200 OK
Set-Cookie: 90plan=R1561091643; path=/; expires=Fri, 20-Mar-2015 11:00:31 GMT
Date: Fri, 20 Mar 2015 09:47:24 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 12311
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

FastCGI + DEFLATE

Il s'agit du mode par défaut d'OVH. Content-Length vaut encore 12311 alors que le contenu est compressé, sa valeur est donc erronée. Avec cette configuration l'évènement on load se déclenche à 5058ms, cela fait plus de 5 secondes ! Et c'est compréhensible puisque le client attend 12311 octets qui ne viendront jamais entièrement. Heureusement qu'il y a un timeout, sinon l'évènement on load ne se déclencherait jamais.

HTTP/1.1 200 OK
Set-Cookie: 90plan=R1561091643; path=/; expires=Fri, 20-Mar-2015 11:00:31 GMT
Date: Fri, 20 Mar 2015 09:48:16 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 12311
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

CGI + GZIP

Pour activer le mode CGI classique il faut éditer le fichier « .ovhconfig » et remplacer app.engine=php par app.engine=phpcgi. Alors évidement c'est moins rapide, mais au moins la valeur de Content-Length est correcte, malgré la compression. Avec cette configuration l'évènement on load se déclenche à 520ms.

HTTP/1.1 200 OK
Set-Cookie: 90plan=R1561091643; path=/; expires=Fri, 20-Mar-2015 10:59:45 GMT
Date: Fri, 20 Mar 2015 09:49:41 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 4866
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

Pourquoi c'est important ?

Outre le fait que la réponse est erronée, c'est surtout très ennuyeux pour tout ce qui concerne JavaScript puisqu'on attend souvent que l'évènement on load se déclenche (le document est chargé) pour faire quoi que ce soit. En d'autre termes, avec un Content-Length erroné les fonctionnalités utilisant JavaScript ne seront disponibles qu'après 5 secondes, ce qui est évidement inacceptable.

Une solution temporaire

En attendant que le problème soit résolu, j'ai choisi de désactiver la compression gzip en utilisant la directive SetEnv no-gzip 1. Ce n'est évidement pas idéal, mais je préfère attendre quelques micro-secondes de plus pour charger la page si ses fonctionnalités sont disponibles immédiatement. C'est vraiment frustrant parce qu'OVH a fait de sérieux efforts depuis l'année dernière en terme de performance. Le bug est connu, alors un dernier effort et ce sera super !

Laisser un commentaire

Un commentaire

Aurélien
Aurélien

bonjour, merci, ça m'a évité (en partie) une grosse prise de tête, je voyais pas la source du problème qui apparemment n'est pas encore résolu il faut croire…