boucle infinie quand on coupe la base de données
Il nous a toujours rassuré sur nos sites de voir que SPIP peut tourner sur le cache sans la base de données, par exemple au cas ou la base de données est coupée, et ceci dans la mesure ou nous conservons un grand nombre de fichiers dans notre cache.
Jusqu'à présent, cela fonctionnait. En désactivant quelques lignes liées à la fonction minipres(), on arrivait à afficher notre site sans base de données, en commentant la ligne dans connect.php et cela sans même que cela ne se voie pour le visiteur.
Depuis notre passage à la version 2.0.8, nous avons testé ce point et nous avons un gros bug. En fait en désactivant la base de données, nos pages bouclent sur elles-mêmes.
Après avoir fait des tests pour remonter la source, je pense être en mesure de donner une piste:
En deconnectant la base de données, la fonction spip_connect_sql() fait appel à la fonction minipres(), qui va afficher un message d'erreur. cette fonction minipres() a un résultat qui dépend de la variable _AJAX. Cette variable est assignée dans spip_initialisation_suite(). Jusqu'ici les choses se faisaient dans l'ordre, et la variable _AJAX était initialisée avant tout appel à minipres().
Lors de l'initialisation de SPIP, on va vérifier si le visiteur a une session d'auteur enregistrée, cela se passe dans utils.php, à la toute fin de spip_initialisation_core(). A ce stade _AJAX n'est pas encore définie car spip_initialisation_core() est apelée avant spip_initialisation_suite().
Depuis la 2.0.8, ce code a été ajouté à la fonction fichier_session():
if (!isset($GLOBALS['meta'][$alea])) {
include_spip('base/abstract_sql');
$GLOBALS['meta'][$alea] = sql_getfetsel('valeur', 'spip_meta', "nom=" . sql_quote($alea));
if (!$GLOBALS['meta'][$alea]){
spip_log("$alea indisponible");
if (!$tantpis) {
include_spip('inc/minipres');
echo minipres();
exit;
}
}
}
Et cette fonction va déclencher un appel à minipres(), que ce soit directement comme on peut le lire ou indirectement par sql_getfetsel(). La valeur de _AJAX n'étant pas attribuée comme souhaité à ce stade, le message de minipres() génère un code javascript qui reload la page, qui apelle a nouveau minipres(), et ainsi de suite.
Pour avoir ce bug et cette boucle infinie, il faut arriver jusqu'à la fonction fichier_session(), c'est à dire si j'ai bien compris, s'être connecté comme auteur en ayant coché la case "se souvenir de moi". Ainsi sans connexion à la base de données on obtient cette boucle.
J'espère m'être fait comprendre et ne pas avoir fait d'erreur dans mon raisonnement, mais l'engrenage est assez complexe à ce niveau et les tests ne sont pas évidents.
Benoit Aubert.