Utilisez FallbackResource même si le répertoire existe


11

J'ai installé mon hôte virtuel sur Apache 2.4.7 avec une configuration très basique:

<VirtualHost *:80>
  ServerName foo.example.com
  DocumentRoot /var/www/html

  DirectoryIndex index.php
  FallbackResource /index.php
</VirtualHost>

Sous la racine du document, j'ai la structure suivante:

/index.php
/help/readme.txt

J'obtiens les résultats suivants lorsque je fais des demandes:

/bla     -> 200 OK
/help/   -> 404 Not Found
/help/a  -> 200 OK

Il semble que l'existence du /help/répertoire provoque le retour d'Apache 404car il n'y index.phpen a pas, mais je m'attends à ce que toutes les demandes soient invoquées /index.phpet donnent donc une 200 OKréponse.

Je ne me souviens pas que ce soit un problème lors de l'utilisation mod_rewrite, mais je préfère utiliser FallbackResourcesi possible. Y'a t'il un moyen d'arranger cela?

Mettre à jour

Cela fonctionne si je supprime la DirectoryIndexdirective, mais cela souffre de problèmes de retard de cinq secondes .

Mise à jour 3

J'exécute l'environnement de test suivant; la structure du répertoire est la suivante:

./htdocs
   index.html
   test/
      bla.txt
./conf
   httpd.conf
./logs

Le contenu de httpd.confest:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

<VirtualHost *:8085>
DocumentRoot /home/user/apache-bug/htdocs

FallbackResource /index.html
</VirtualHost>

Mon config.nicecontient:

"./configure" \
"--enable-debugger-mode" \
"--with-apr=/usr/local/apr/bin/apr-1-config" \
"--enable-dir=static" \
"--with-mpm=prefork" \
"--enable-unixd=static" \
"--enable-authn-core=static" \
"--enable-authz-core=static" \
"$@"

Pour exécuter le serveur:

httpd -X -d /home/user/work/apache-bug/

Et à quoi sert le corps de réponse /bla?
zerkms

Je ne suis pas sûr de comprendre le problème alors: -S
zerkms

Juste pour vous assurer - sur quelle version d'Apache êtes-vous?
Jenny D

@JennyD J'utilise le 2.4.7.
Jack

Réponses:


8

Je réponds également à cette question moi-même, car je suis à peu près sûr que le problème est lié au mod_dir.cfonctionnement interne et je pense que c'est un bug .

Si une ressource ne peut pas être mappée au système de fichiers local, la fonction fixup_dflt()s'exécutera en utilisant le FallbackResourcepour déterminer le document à charger à la place.

Cependant, lorsqu'une ressource peut être mappée au système de fichiers local et qu'il s'agit d'un répertoire, elle tentera de résoudre le document en exécutant fixup_dir(); cette fonction parcourt la liste de DirectoryIndexvaleurs jusqu'à ce qu'elle trouve le premier document approprié.

Dans mon cas, la configuration a une liste de DirectoryIndexvaleurs vide , donc fixup_dir()échouera et un 404 est retourné.

Le patch suivant fonctionne pour moi ( PR ):

static int dir_fixups(request_rec *r)
{
    if (r->finfo.filetype == APR_DIR) {
-        return fixup_dir(r);
+        if (fixup_dir(r) != OK) {
+           /* use fallback */
+           return fixup_dflt(r);
+        }
+
+        return OK;
    }
    else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
        /* No handler and nothing in the filesystem - use fallback */
        return fixup_dflt(r);
    }
    return DECLINED;
}

Il essaie essentiellement fixup_dflt()après avoir fixup_dir()échoué.

Mise à jour 2015-04-21

Un correctif a été soumis au projet, prévu pour 2.5; il peut également être porté sur 2.4.

Mise à jour 2015-05-18

Le correctif a été annulé car:

[...] cela [au moins] provoque un FallBackResourcecoup de pied avant qu'il mod_autoindexn'ait pu entrer en jeu.

J'essaie toujours de comprendre comment éviter ce genre de situation.


Je dirais que l'erreur consiste à fixup_dir()ignorer FallbackResource.
Ricky Beam

@RickyBeam Oui, mais techniquement fixup_dir()ne devrait pas savoir fixup_dflt(), alors à mon humble avis, il vaut mieux le réparer "plus haut" :)
Jack

7

Votre configuration doit être correcte.

Curieusement , le problème semble être mod_deflate .

Après avoir reproduit votre configuration avec succès ici ( sans obtenir de 404), j'ai également eu le délai de 5 secondes. Cependant, j'ai remarqué que lorsque l'UA omet gzipde ses Accept-Headers, la page est affichée / reçue instantanément. Vous pouvez tester cela par vous-même wget.

Fait intéressant, un débogage supplémentaire avec stracemontre qu'apache envoie le contenu de votre FallbackResourceà la prise de votre client sans différence notable de délai dans les deux cas. Cela est également évident sur le câble, où un paquet de réponse est envoyé du serveur au client après la requête HTTP sans délai notable 1 .

Il semble cependant que lors de l'utilisation de mod_deflate dans ce cas, l'UA ne sait pas quand les données envoyées par le serveur se terminent et ne rendent donc rien avant l'expiration de la connexion TCP 2 et sont fermées de force par le serveur. Ceci est conforme à HTTP / 1.0, où une connexion fermée signifie la fin du contenu.

Pour HTTP / 1.1 , le serveur dispose d'autres moyens pour signaler la fin du contenu - mais aucun ne semble se produire ici .

Que le bogue se cache dans mod_dir ou mod_deflate cependant, est au-delà de mon temps disponible en ce moment. Je l'ai fait fonctionner sans problème en désactivant la compression gzip; comme solution de contournement jusqu'à ce que le problème soit résolu pour de bon, vous pouvez désactiver sélectivement gzip.

1 ) Cela nous indique que le problème ne provient pas de tampons non vidés sur le serveur.
2 ) Par défaut, le délai d'attente est de 5 secondes avec apache - c'est de là que viennent vos 5 secondes.


Merci. Le problème de retard 5s est secondaire à mon problème principal, j'ai mis à jour ma question avec la façon de reproduire le problème localement.
Jack
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.