Apache : « AH01797: client denied by server configuration » sur le dossier icons

Un client m’a remonté que sur son site le favicon était en erreur 404, de façon incompréhensible.

Si j’essaye d’accéder au favicon avec mon navigateur, j’ai bien une erreur 404. Et dans les logs je vois :

[Fri Feb 26 11:38:36.170743 2021] [access_compat:error] [pid 11523:tid 139967505688320] [client XXX.XXX.XXX.XXX:0] AH01797: client denied by server configuration: [...]/current/favicon.ico

Pourtant le fichier favicon.ico est bien présent au bon emplacement et avec les bons droits.

 

J’ai dû pas mal chercher pour trouver la source du problème. C’est ce site qui m’a aidé.

En fait, le module alias contiens par défaut la configuration suivante :

        # We include the /icons/ alias for FancyIndexed directory listings.  If
        # you do not use FancyIndexing, you may comment this out.

        Alias /icons/ "/usr/share/apache2/icons/"

        <Directory "/usr/share/apache2/icons">
                Options FollowSymlinks
                AllowOverride None
                Require all granted
        </Directory>

Sur tous les vhosts du serveur, le dossier /icons/ est réécrit vers /usr/share/apache2/icons/, donc toutes les icônes ajoutées par le client ne sont pas accessibles.

La solution évoquée sur le site est de renommer le dossier /icons/ sur le site. Ça ne me conviens pas, parce-qu’il faut que le client modifie son site. La seule solution est de commenter ces lignes.

Drupal et PostgreSQL : Error at offset 0 of … bytes drupal/includes/cache.inc

Il y a quelques jours j’ai dû copier un site Drupal de prod vers un autre serveur, pour en faire une préprod. Malgré une configuration qui semblait entièrement ISO, j’avais une plâtrée de messages d’erreur, du type :

Notice: unserialize(): Error at offset 0 of 1009 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 1009 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 13 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Fatal error: Call to undefined function system_run_automated_cron() in [...]drupal/includes/common.inc on line 2784
Il m’a fallu du temps pour trouver comment corriger ce problème. (d’ailleurs c’est même pas moi qui ai trouvé)
D’après internet, ces messages indiquent un problème dans la sérialisation des données.
Drupal a une drôle de façon de stocker ses données. Par exemple, si sur le serveur de base de données de prod je fais un :

SELECT variables FROM watchdog WHERE wid=10969;

ça me retournes :

a:2:{​​​​​​​s:5:"@type";s:4:"page";s:6:"%title";s:52:"Titre chelou, j'ai pas le droit de mettre le vrai";}

Je ne sais pas pourquoi ils ont fait ça, mais Drupal utilise une base de données PostgreSQL pour ensuite stocker des données formatées en JSON.
Maintenant, si je fais la même requête sur le serveur de base de données de préprod, j’ai :

\x5469747265206368656C6F752C206A27616920706173206C652064726F6974206465206D6574747265206C652076726169

Le résultat est retourné au format hexadécimal. Si on le convertit en texte, on obtient bien la même chaîne que sur le serveur de prod. C’est juste le format de la donnée qui est différente.
En fait le serveur de base de données de prod avait été installé avec PostgreSQL 8, puis a ensuite été mis à jour vers PostgreSQL 9. Le serveur de prérpod, plus récent, a été installé directement en version 9.
Sauf qu’entre les versions 8 et 9 de PostgreSQL, la gestion par défaut des données a changé
Ce qui me pose problème dans ce cas précis, c’est le bytea_output, qui est à escape en prod, mais à hex en préprod. Ca se corrige très simplement avec :

ALTER DATABASE nom_de_la_base SET bytea_output to 'escape';