[spip-dev] bug : SPIP 1.7.2 - probleme de cache avec Mozilla

bonjour,

je viens d'installer la version courante de SPIP. j'ai constaté un probleme
de gestion du cache avec Mozilla a partir des version 1.41. Les versions
1.2 et 1.3 n'ont pas ce probleme. Il n'a pas de soucis avec Netscape 7.02
sur la meme plateforme Linux.

De meme sur plateforme Windows il n'y a pas de soucis avec IE6, un mozilla
1.2 et Netscape.

Le bug constaté est le suivant :

  - un clic sur une page qui n'est pas en cache (du navigateur) est bien
chargée correctement.

  - je suppose qu'a la suite de ce clic, la page est mise en cache.
  - si j'accede a nouveau a la meme page (clic, reload, ou lien sur
meme page) j'obtient une page vide.
  - le cache du navigateur contient bien une page vide.
  - cette erreur est aussi présente quand je supprimes mes squellete
et que je laisse agir les squelettes par defaut.
  - un acces infructueux a une page avec Mozilla donne ceci dans le fichier
de log :

May 27 15:01:56 143.196.38.143 (pid 27175) article 59 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) auteur 25 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) breve 32 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) mot 160 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) rubrique 158 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) syndic 22 deja indexe

  - le meme type d'acces sur Netscape ne donne pas de trace
dans le fichier de log.

est-ce que ce petit probleme est constaté ailleurs que chez moi ?

Marc Quinton a écrit :

bonjour,

je viens d'installer la version courante de SPIP. j'ai constaté un probleme
de gestion du cache avec Mozilla a partir des version 1.41. Les versions
1.2 et 1.3 n'ont pas ce probleme. Il n'a pas de soucis avec Netscape 7.02
sur la meme plateforme Linux.

De meme sur plateforme Windows il n'y a pas de soucis avec IE6, un mozilla
1.2 et Netscape.

Le bug constaté est le suivant :

- un clic sur une page qui n'est pas en cache (du navigateur) est bien
chargée correctement.

- je suppose qu'a la suite de ce clic, la page est mise en cache.
- si j'accede a nouveau a la meme page (clic, reload, ou lien sur
meme page) j'obtient une page vide.
- le cache du navigateur contient bien une page vide.
- cette erreur est aussi présente quand je supprimes mes squellete
et que je laisse agir les squelettes par defaut.
- un acces infructueux a une page avec Mozilla donne ceci dans le fichier
de log :

May 27 15:01:56 143.196.38.143 (pid 27175) article 59 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) auteur 25 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) breve 32 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) mot 160 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) rubrique 158 deja indexe
May 27 15:01:56 143.196.38.143 (pid 27175) syndic 22 deja indexe

- le meme type d'acces sur Netscape ne donne pas de trace
dans le fichier de log.

est-ce que ce petit probleme est constaté ailleurs que chez moi ?

Oui :frowning:

Marc Quinton a écrit :

est-ce que ce petit probleme est constaté ailleurs que chez moi ?

Bug constaté sur la plateforme suivante : Mandrake 9.2 avec Mozilla 1.4 (?), Apache2, PHP 4.3.x et MySQL 4.x (paquets de mandrake à chaque fois). Dans ce cas il s'agissait d'une utilisation/consultation en local.

De mémoire, depuis un poste sous Windows et en consultant le pc ci-dessus, il me semble que le bug se reproduisait sous Moz 1.6.

Par contre, je n'ai pas eu le temps de partir à la chasse au bug, ni à une identification plus avancée.

Sous Mandrake 10, je n'ai plus ce problème (enfin plus à ce jour).

Nicolas

Nicolas Steinmetz wrote:

Marc Quinton a écrit :

est-ce que ce petit probleme est constaté ailleurs que chez moi ?

Bug constaté sur la plateforme suivante : Mandrake 9.2 avec Mozilla 1.4 (?), Apache2, PHP 4.3.x et MySQL 4.x (paquets de mandrake à chaque fois). Dans ce cas il s'agissait d'une utilisation/consultation en local.

pour ma part, voici les versions exactes :
- RH 8.0,
- php 4.2.2,
- mysql 3.23.58
- apache 2.0

je n'ai pas ce probleme avec SPIP 1.6, et 1.7

Marc Quinton wrote:

Nicolas Steinmetz wrote:

Marc Quinton a écrit :

est-ce que ce petit probleme est constaté ailleurs que chez moi ?

Bug constaté sur la plateforme suivante : Mandrake 9.2 avec Mozilla 1.4 (?), Apache2, PHP 4.3.x et MySQL 4.x (paquets de mandrake à chaque fois). Dans ce cas il s'agissait d'une utilisation/consultation en local.

pour ma part, voici les versions exactes :
- RH 8.0,
- php 4.2.2,
- mysql 3.23.58
- apache 2.0

je n'ai pas ce probleme avec SPIP 1.6, et 1.7

je viens de voir que sur la seconde demande, celle qui retourne une page
vide, apache renvoie un code de retour 304, ce qui signifie qu'il considere
que la page est toujours actuelle. Maintenant, reste a comprendre pourquoi
cela engendre une erreur avec certaines versions de mozilla et pas avec
d'autres, et si ce code 304 est envoyé par SPIP ou par apache.

je viens de voir que sur la seconde demande, celle qui retourne une page
vide, apache renvoie un code de retour 304, ce qui signifie qu'il considere
que la page est toujours actuelle. Maintenant, reste a comprendre pourquoi
cela engendre une erreur avec certaines versions de mozilla et pas avec
d'autres, et si ce code 304 est envoyé par SPIP ou par apache.

Apparemment c'est une discussion qui revient sans cesse :
http://www.spip.net/threadspip2014-5011.html
http://www.spip.net/threadspip2015-5854.html
http://article.gmane.org/gmane.comp.web.spip.devel/17753

-- Fil

Apache enregistre dans les logs un code 304, mais SPIP (?) envoie un code 200
avec juste du vide.

Revoir le thread dont Fil parlait, je dois donner accès à une de mes machines
qui a ce problème à Antoine pour qu'il trouve le bogue. Si jamais vous avez
les compétences, j'avais des bribes de diagnostic dans le thread mais j'étais
incapable d'aller plus loin.

Bonjour,

J'ai vu sur la liste de dev de SPIP-Agora qqn qui a un problème similaire.

La réponse qui lui a été donnée est la suivante :

"Si tu as apache 2, il faut désactiver la compression zlib dans ton php.ini."

Cela peut être une piste (pas testé de mon côté)

Nicolas

Benoit St-Andre wrote:

Apache enregistre dans les logs un code 304, mais SPIP (?) envoie un code 200 avec juste du vide.

ce n'est pas ce que me disent les logs du serveur Apache

[cautra@intrux SPIP-v1-7-2]$ tail -1000 /var/log/httpd/access_log | grep spip-dev2/sommaire.php
143.196.38.143 - - [02/Jun/2004:07:46:05 +0200] "GET /activ/cautra/spip-dev2/sommaire.php3 HTTP/1.1" 200 31381 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007"
143.196.38.143 - - [02/Jun/2004:07:47:17 +0200] "GET /activ/cautra/spip-dev2/sommaire.php3 HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007"

je meme, le fichier spip.log contient des traces intéressantes ; j'ai posé quelque
demandes de traces via la fonction spip_log

Jun 02 07:46:05 143.196.38.143 (pid 16509) inc-public : MQ : ----------- debut inc-public-global : sommaire

quelques essais sur plateforme Windows :

* Mozilla 1.2

- en configurant le cache de maniere a ce que le navigateur
verifie a chaque demande si la page est toujours d'actualité
je me trouve avec le meme bug, la meme reponse 403.
- Mozilla envoie bien une requete avec le champ If-Modified-Since.
ce champ est detecté par SPIP qui analyse son cache et envoie sa
réponse.

* IE6 :

- Concernant IE6, je n'arrive pas a reproduire le bug. D'ailleurs
IE6 n'envoie pas le champ If-Modified-Since malgrés la configuration
du cache local. La gestion du cache de IE6 n'est pas aussi performante
et sans doute pas tout a fait conforme a ce qui devrait etre un standard.
Donc a chaque requete, IE6 ne transmettant pas le If-Modified-Since
se retrouve avec la page au complet, au lieu de faire la demande
"est-ce que la page est encore valide ?" et d'obtenir une reponse 403.

* anciennes versions de SPIP.

- les anciennes versions de SPIP contiennent "globalement" le meme code
pour la gestion du cache et des reponses http
- la différence s'il y en a une est particulierement ténue

* Apache

- j'ai du mal a mettre en cause Apache et sa configuration. Et pour cause
j'ai en production 2 SPIP sur le meme serveur, pratiquement dans la meme
arborescence et sur le meme compte Unix. Une version 1.6 qui fonctionn
parfaitement, et une version 1.7.0 qui ne m'a pas posé de soucis particulier
mais une 1.7.2 qui a ces problemes.

excusez-moi pour ceux qui ne sont pas concernés par ce probleme pour
mes messages un peu nombreux. Je tiens a faire avancer ce probleme
rapidement.

Voici un script php d'expérimentation pour les plus intéressés. Il s'agit
de gerer un pseudo cache et de generer a la SPIP des codes de retour 403
a la demande. Il est ensuite possible d'observer la requete soumise
par le navigateur.

L'ideal serait de disposer d'un formulaire pour modifier dynamiquement
le comportement, mais c'est un risque de ne pas etre en configuration
similaire au cas que nous avons sur SPIP. Ce script vaut ce qu'il vaut
a ne pas prendre pour argent comptant.

cat http_header.php

<?php

$cache_delay = 30; # 5 secondes
$log_msg = "";

$reload = $_REQUEST['reload'];

# $last_mod = time();
$last_mod = filemtime("http_header.php");
log_text("last_mod = $last_mod");

$response = 2;
switch ($response){
  case 1:
  http_header($last_mod, $last_mod + $cache_delay);
     break;
  case 2:
  http_last_modified($last_mod, $last_mod + $cache_delay);
     break;
  case 3:
    http_status(304);
  exit(0);
     break;
}

function http_header($last_mod, $expire){

   @Header ("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_mod)." GMT");
   @Header ("Expires: ".gmdate("D, d M Y H:i:s", $expire)." GMT");
}

# Tue, 01 Jun 2004 13:54:44
# Tue, 01 Jun 2004 12:59:36 GMT
# Tue, 01 Jun 2004 11:54:44 GMT
# Tue, 01 Jun 2004 12:59:36

function log_text($msg){
   global $log_msg;
   $log_msg .= $msg . "\n";
}

function log_print(){
   global $log_msg;
   echo "$log_msg";
}

function http_status($status) {
         $status_string = array(
                 200 => '200 OK',
                 304 => '304 Not Modified',
                 401 => '401 Unauthorized',
                 403 => '403 Forbidden',
                 404 => '404 Not Found'
         );
         if ($php_cgi) Header("Status: $status");
         else Header("HTTP/1.0 ".$status_string[$status]);
}

function http_last_modified($lastmodified, $expire = 0) {
         $gmoddate = gmdate("D, d M Y H:i:s", $lastmodified);
    log_text("http_last_modified() : gmoddate = $gmoddate");
         if ($GLOBALS['HTTP_IF_MODIFIED_SINCE']) {
        log_text("HTTP_IF_MODIFIED_SINCE");
                 $if_modified_since = ereg_replace(';.*$', '', $GLOBALS['HTTP_IF_MODIFIED_SINCE']);
                 $if_modified_since = trim(str_replace('GMT', '', $if_modified_since));
        log_text("HTTP_IF_MODIFIED_SINCE = " . $GLOBALS['HTTP_IF_MODIFIED_SINCE']);
        log_text("if_modified_since = $if_modified_since");
                 if ($if_modified_since == $gmoddate) {
               log_text("if_modified_since = $if_modified_since");
                     http_status(304);
                     $headers_only = true;
                 }
         }
         @Header ("Last-Modified: ".$gmoddate." GMT");
    log_text("http_last_modified() : gmoddate = $gmoddate");
         if ($expire)
                 @Header ("Expires: ".gmdate("D, d M Y H:i:s", $expire)." GMT");

         return $headers_only;
}

?>

Header - Last-modified test program
<br>

<li><a href="http_header.php?reload=false">reload</a>, <a href="http_header.php?reload=true">force reload</a>,
<li>time = <?php echo time() . " / " . gmdate("D, d M Y H:i:s", time()); ?>
<li>reload = <? echo $reload ?>
<pre>

<?php

   print_r($_SERVER);

   echo "\n\n------ log -----------\n";
   log_print();
?>

</pre>

Marc Quinton wrote:

- j'ai du mal a mettre en cause Apache et sa configuration. Et pour cause
j'ai en production 2 SPIP sur le meme serveur, pratiquement dans la meme
arborescence et sur le meme compte Unix. Une version 1.6 qui fonctionn
parfaitement, et une version 1.7.0 qui ne m'a pas posé de soucis particulier
mais une 1.7.2 qui a ces problemes.

le bug est dans les 1.7* et pas dans 1.6. Sur 1.6 les sources sont
vraiment différents. Il ne gerent pas la reponse http 403.

j'ai du mal a comprendre comment ce bug n'est pas apparu plus
rapidement. A croire que je suis le seul a utiliser Mozilla et
SPIP simultanément ...

le bug est dans les 1.7* et pas dans 1.6. Sur 1.6 les sources sont
vraiment différents. Il ne gerent pas la reponse http 403.

j'ai du mal a comprendre comment ce bug n'est pas apparu plus
rapidement. A croire que je suis le seul a utiliser Mozilla et
SPIP simultanément ...

Que vaut ton PHP: php_sapi_name - Manual ?
<?php echo php_sapi_name(); ?>

-- Fil

petit complément d'information :

* le fait d'etre connecté en tant qu'administrateur du site,
* d'avoir positionné l'option "rester connecter plusieurs jours"

semble avoir un impact sur la gestion du cache.

Peux-tu commenter les lignes envoyant un en-tête "Vary" dans
inc_version.php3 pour voir si ça change qqch ?

Est-ce que le problème disparaît si tu te déconnectes de l'espace privé
?

Autre possibilité : dans la fonction http_last_modified
(inc_version.php3), rajouter la ligne suivante à la fin :

if ($headers_only) while (@ob_end_clean());

Antoine wrote:

petit complément d'information :

* le fait d'etre connecté en tant qu'administrateur du site,
* d'avoir positionné l'option "rester connecter plusieurs jours"

semble avoir un impact sur la gestion du cache.

Autre possibilité : dans la fonction http_last_modified
(inc_version.php3), rajouter la ligne suivante à la fin :

if ($headers_only) while (@ob_end_clean());

non ca ne corrige pas le probleme ;

j'ai aussi essayé de supprimer le mode buffurisé et compressé
comme ca :

ecrire/inc_version.php :
$flag_gz = function_exists("gzopen");
$flag_ob = ($flag_ini_get
         && !ereg("ob_", ini_get('disable_functions'))
         && function_exists("ob_start"));
$flag_obgz = ($flag_ob && function_exists("ob_gzhandler"));
#MQ
$flag_ob = false;
$flag_obgz = false;
$flag_gz=false;

ca ne change pas le fonctionnement. J'ai toujours la page blanche.
ce n'est donc pas a prioris, un probleme de buffering non vidé, ou de reponse
compressée.

> Peux-tu commenter les lignes envoyant un en-tête "Vary" dans
> inc_version.php3 pour voir si ça change qqch ?

oui ca change bien qq chose !!!

si je commente les 2 lignes, il n'y a plus d'erreur certe, mais
il n'y a plus de négociation de page et la page est systématiquement
transmise. Il n'y a plus de reponse 304 de la part de spip, et
c'est un peu dommage, non ...

Non, c'est l'inverse : Mozilla n'envoie pas du tout de If-Modified-Since
et utilise directement sa copie cachée. (mais c'est un comportement
invalide puisque le contenu dépend des cookies)

Dans inc-public-global.php3, derrière l'appel à http_last_modified(),
peux-tu ajouter la ligne suivante :
  if ($headers_only) exit;

Il est possible que le bug vienne d'une non-conformité avec la RFC :

« The 304 response MUST NOT contain a message-body, and thus is always
terminated by the first empty line after the header fields.

The response MUST include the following header fields:
      - Date, unless its omission is required by section 14.18.1 »

a+

Antoine.

Antoine wrote:

Dans inc-public-global.php3, derrière l'appel à http_last_modified(),
peux-tu ajouter la ligne suivante :
  if ($headers_only) exit;

parfait !!

maintenant, j'ai toujours la reponse 304 dans mes log apache,
mais Mozilla sait interpréter la reponse et considere que la page
est encore a jour et ne fait que l'afficher.

le probleme est donc que a la suite de la réponse 304, il y a
un bout de corp de message qui est envoyé.

seul soucis, c'est que les taches de fond ne sont plus activées
suite a exit(). Mais nous avons maintenant le principal :
  - une page qui n'est pas blanche
  - une bonne gestion du cache par SPIP et par le navigateur.

Dans inc-public-global.php3, derrière l'appel à http_last_modified(),
peux-tu ajouter la ligne suivante :
  if ($headers_only) exit;

parfait !!

maintenant, j'ai toujours la reponse 304 dans mes log apache,
mais Mozilla sait interpréter la reponse et considere que la page
est encore a jour et ne fait que l'afficher.

le probleme est donc que a la suite de la réponse 304, il y a
un bout de corp de message qui est envoyé.

seul soucis, c'est que les taches de fond ne sont plus activées
suite a exit().

Plutot que le exit:
  header("Connection: close");
devrait etre la solution 100% satisfaisante.

      Emmanuel

Déesse A. wrote:

Plutot que le exit:
header("Connection: close");
devrait etre la solution 100% satisfaisante.

non, ca marche pas chez moi.
l'idée etait particulierement séduisante. C'est beau l'intelligence collective :wink: