Use FallbackResource mesmo se o diretório existir

11

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 /help/diretório está causando o retorno do Apache 404porque não há nenhum index.php, mas espero que todas as solicitações sejam invocadas /index.phpe, portanto, produzam uma 200 OKresposta.

Não me lembro de isso ser um problema ao usar mod_rewrite, mas prefiro usá-lo, FallbackResourcese possível. Existe uma maneira de corrigir isso?

Atualizar

Funciona se eu remover a DirectoryIndexdiretiva, mas isso sofre com problemas de atraso de cinco segundos .

Atualização 3

Estou executando o seguinte ambiente de teste; a estrutura de diretórios é 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.niceconté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/
Jack
fonte
E para que serve o corpo de resposta /bla?
Zerkms
Não tenho certeza de que estou entendendo o problema:
zerkms
Apenas para ter certeza - em qual versão do Apache você está?
Jenny D
@ JennyD Estou executando o 2.4.7.
Jack

Respostas:

8

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

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

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

No meu caso, a configuração tem uma lista vazia de DirectoryIndexvalores, portanto 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;
}

Basicamente, tenta fixup_dflt()depois de fixup_dir()falhar.

Atualização 2015-04-21

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

Atualização 18/05/2015

A correção foi revertida porque:

[...] [pelo menos] faz FallBackResourcechutar antes que mod_autoindexpossa ter chutado.

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

Jack
fonte
Eu diria que o erro está em fixup_dir()ignorar o FallbackResource.
Ricky feixe
@RickyBeam Sim, mas tecnicamente fixup_dir()não deve saber sobre fixup_dflt(), por isso, IMHO é melhor para corrigi-lo "mais acima" :)
Jack
7

Sua configuração deve estar correta.

O problema, estranhamente, parece ser mod_deflate .

Depois de reproduzir sua configuração com sucesso aqui ( sem obter um 404), também recebi o atraso de 5 segundos. No entanto, notei que, quando o UA omite gzipseus Accept-Headers, a página é exibida / recebida instantaneamente. Você pode testar isso sozinho wget.

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

Parece que, ao usar mod_deflate nesse caso, no entanto, 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 seja fechada à força pelo servidor. Isso é compatível com HTTP / 1.0, onde uma conexão fechada significa final do conteúdo.

Para HTTP / 1.1 , o servidor tem outros meios disponíveis para sinalizar o final do conteúdo - mas nenhum dos quais parece acontecer aqui .

Se o bug está oculto no mod_dir ou mod_deflate, está além do meu tempo disponível no momento. Consegui que funcionasse perfeitamente, desativando a compactação gzip; como uma solução alternativa até que o problema seja resolvido definitivamente, você pode desativar seletivamente o gzip.

1 ) Isso nos diz que o problema não decorre de buffers não liberados no servidor.
2 ) Por padrão, o tempo limite é de 5 segundos no apache - é daí que são os seus 5 segundos.

romano
fonte
Obrigado. O problema do atraso 5s é secundário ao meu problema principal. Atualizei minha pergunta sobre como reproduzir o problema localmente.
Jack