Use FallbackResource mesmo se o diretório existir

10

Eu configurei meu host virtual no Apache 2.4.7 com uma configuração muito básica:

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

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

Abaixo da raiz do documento, tenho a seguinte estrutura:

/index.php
/help/readme.txt

Recebo os seguintes resultados quando faço solicitações:

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

Parece que a existência do diretório /help/ está fazendo com que o Apache retorne 404 porque não há index.php , mas espero que todas as solicitações invoquem /index.php e, assim, gerem uma resposta 200 OK .

Não me lembro de ser um problema ao usar mod_rewrite , mas prefiro usar FallbackResource , se possível. Existe uma maneira de corrigir isso?

Atualizar

Funciona se eu remover a diretiva DirectoryIndex , mas isso sofre de cinco segundos atrasos .

Atualização 3

Estou executando o seguinte ambiente de teste; a estrutura do diretório é a seguinte:

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

O conteúdo de httpd.conf é:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

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

FallbackResource /index.html
</VirtualHost>

Meu config.nice contém:

"./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" \
"$@"

Para executar o servidor:

httpd -X -d /home/user/work/apache-bug/
    
por Jack 22.01.2014 / 02:57

2 respostas

8

Também estou respondendo a isso, porque tenho certeza de que o problema está relacionado a como mod_dir.c funciona internamente e eu acho que é um bug .

Se um recurso não puder ser mapeado para o sistema de arquivos local, a função fixup_dflt() será executado, usando o FallbackResource para determinar qual documento deve ser carregado.

No entanto, quando um recurso pode ser mapeado para o sistema de arquivos local e é um diretório, ele tentará resolver o documento executando fixup_dir() ; essa função percorre a lista de valores DirectoryIndex até encontrar o primeiro documento adequado.

No meu caso, a configuração tem uma lista vazia de DirectoryIndex valores, então fixup_dir() falhará e um 404 será retornado.

O seguinte patch funciona para mim ( 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;
}

Ele basicamente tenta fixup_dflt() depois que fixup_dir() falhou.

Atualização 2015-04-21

Uma correção foi enviada ao projeto, programada para 2,5; pode ser portado para 2.4 também.

Atualização 2015-05-18

A correção foi revertida porque:

[...] it [at least] causes FallBackResource to kick in before mod_autoindex might have kicked in.

Ainda estou tentando descobrir como evitar esse tipo de situação.

    
por 27.01.2014 / 07:26
7

Sua configuração deve estar correta.

O problema, estranhamente, parece ser mod_deflate .

Depois de ter reproduzido sua configuração com sucesso aqui ( não obtendo um 404), eu também recebi o atraso de 5 segundos. No entanto, notei que quando o UA omite gzip de seus Accept-Headers, a página é exibida / recebida instantaneamente. Você pode testar isso com wget .

Curiosamente, uma depuração adicional com strace mostra que o apache envia o conteúdo de seu FallbackResource para o soquete de seu cliente sem diferença perceptível no atraso para os casos ambos . Isso também é evidente na ligação, onde um pacote de resposta é enviado do servidor para o cliente após a solicitação HTTP sem qualquer atraso notável 1 .

Parece que, ao usar mod_deflate neste caso, o UA não sabe quando os dados enviados pelo servidor terminam e, portanto, não renderiza nada antes que a conexão TCP expire 2 e é forçosamente fechado pelo servidor. Isso é compatível com HTTP / 1.0, em que uma conexão fechada significa fim de conteúdo.

Para HTTP / 1.1 , o servidor tem outros meios disponíveis para sinalizar o fim of-content - mas nenhum deles parece acontecer aqui .

Se o bug estiver escondido em mod_dir ou mod_deflate, estará além do meu tempo disponível no momento. Consegui que funcionasse sem falhas, desabilitando a compressão gzip; como uma solução alternativa até que o problema seja corrigido para sempre, você pode desativar seletivamente o gzip.

1 ) Isso nos diz que o problema não provém de buffers não-reduzidos no servidor.
2 ) Por padrão, o tempo limite é de 5 segundos com o apache - é de onde são seus 5 segundos.

    
por 24.01.2014 / 14:34