Gunakan FallbackResource bahkan jika direktori ada

11

Saya telah mengatur host virtual saya di Apache 2.4.7 dengan konfigurasi yang sangat mendasar:

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

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

Di bawah root dokumen saya memiliki struktur berikut:

/index.php
/help/readme.txt

Saya mendapatkan hasil berikut ketika saya membuat permintaan:

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

Tampaknya keberadaan /help/direktori menyebabkan Apache untuk kembali 404karena tidak ada index.phpdi sana, tapi saya berharap semua permintaan untuk memanggil /index.phpdan dengan demikian menghasilkan 200 OKrespons.

Saya tidak ingat ini menjadi masalah saat menggunakan mod_rewrite, tapi saya lebih suka menggunakan FallbackResourcejika memungkinkan. Apakah ada cara untuk memperbaikinya?

Memperbarui

Ini berfungsi jika saya menghapus DirectoryIndexarahan, tetapi itu menderita masalah keterlambatan lima detik .

Perbarui 3

Saya menjalankan lingkungan pengujian berikut; struktur direktori adalah sebagai berikut:

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

Isinya httpd.confadalah:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

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

FallbackResource /index.html
</VirtualHost>

Saya config.nicemengandung:

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

Untuk menjalankan server:

httpd -X -d /home/user/work/apache-bug/
Mendongkrak
sumber
Dan untuk apa tubuh tanggapan /bla?
zerkms
Saya tidak yakin saya memahami masalah itu: -S
zerkms
Hanya untuk memastikan - versi Apache mana yang Anda pakai?
Jenny D
@ Jenny, saya menjalankan 2.4.7.
Jack

Jawaban:

8

Saya sendiri juga menjawab ini, karena saya cukup yakin bahwa masalah ini terkait dengan cara mod_dir.ckerja internal dan saya pikir ini adalah bug .

Jika sumber daya tidak dapat dipetakan ke sistem file lokal, fungsi fixup_dflt()akan berjalan, menggunakan FallbackResourceuntuk menentukan dokumen mana yang harus dimuat.

Namun, ketika sumber daya dapat dipetakan ke sistem file lokal dan itu adalah direktori, itu akan berusaha menyelesaikan dokumen dengan menjalankan fixup_dir(); fungsi ini berulang pada daftar DirectoryIndexnilai sampai menemukan dokumen yang sesuai pertama.

Dalam kasus saya, konfigurasi memiliki daftar DirectoryIndexnilai kosong , sehingga fixup_dir()akan gagal dan 404 dikembalikan.

Patch berikut berfungsi untuk saya ( 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;
}

Itu pada dasarnya mencoba fixup_dflt()setelah fixup_dir()gagal.

Perbarui 2015-04-21

Sebuah memperbaiki telah disampaikan kepada proyek, yang dijadwalkan selama 2,5; mungkin porting ke 2.4 juga.

Perbarui 2015-05-18

Perbaikan telah dikembalikan karena:

[...] itu [setidaknya] menyebabkan FallBackResourceuntuk menendang sebelum mod_autoindexmungkin menendang.

Saya masih mencoba mencari cara untuk menghindari situasi seperti ini.

Mendongkrak
sumber
Saya akan mengatakan kesalahan dalam fixup_dir()mengabaikan FallbackResource.
Ricky Beam
@ RickyBeam Ya, tetapi secara teknis fixup_dir()tidak seharusnya tahu fixup_dflt(), jadi sebaiknya saya memperbaikinya "lebih tinggi" :)
Jack
7

Konfigurasi Anda harus benar.

Masalahnya, anehnya, tampaknya mod_deflate .

Setelah berhasil mereproduksi konfigurasi Anda di sini ( tidak mendapatkan 404), saya juga mendapat penundaan 5 detik. Namun, saya perhatikan bahwa ketika UA menghilangkan gzipdari Terima-Headernya, halaman ditampilkan / diterima secara instan. Anda dapat menguji ini sendiri wget.

Menariknya, lebih lanjut dengan debugging stracemenunjukkan bahwa apache mengirimkan konten Anda FallbackResourceke soket klien Anda tanpa ada perbedaan keterlambatan yang nyata untuk kedua kasus tersebut. Ini juga terbukti pada kawat, di mana paket balasan dikirim dari server ke klien setelah Permintaan HTTP tanpa penundaan 1 .

Tampaknya ketika menggunakan mod_deflate dalam kasus ini, UA tidak tahu kapan data yang dikirim oleh server berakhir, dan dengan demikian tidak membuat apa pun sebelum koneksi TCP habis 2 dan secara paksa ditutup oleh server. Ini sesuai dengan HTTP / 1.0, di mana koneksi tertutup menandakan konten akhir.

Untuk HTTP / 1.1 , server memiliki cara lain yang tersedia untuk memberi sinyal akhir konten - tetapi tidak ada yang tampaknya terjadi di sini .

Namun apakah bug bersembunyi di mod_dir atau mod_deflate namun, sudah melampaui waktu saya yang tersedia sekarang. Saya membuatnya bekerja tanpa cacat dengan menonaktifkan kompresi gzip; sebagai solusi sampai masalah ini diperbaiki untuk selamanya, Anda dapat menonaktifkan gzip secara selektif.

1 ) Ini memberitahu kita bahwa masalahnya bukan berasal dari buffer yang tidak diblush di server.
2 ) Secara default, batas waktu adalah 5 detik dengan apache - dari sanalah 5 detik Anda berasal.

Roma
sumber
Terima kasih. Masalah keterlambatan 5s adalah masalah sekunder saya, saya telah memperbarui pertanyaan saya dengan cara mereproduksi masalah secara lokal.
Jack