Perbedaan eksplisit antara <Directory> dan <DirectoryMatch> (dan arahan <* Match> lainnya)

8

Kata pengantar

Saya sangat baru tentang webservers. Saya sedang menyiapkan server Apache2 dan saat ini sedang meneliti dokumentasi.

Saya melihat bahwa <Directory>, <Location>, dan <Files>arahan masing-masing memiliki sesuai <*Match>direktif: <DirectoryMatch>, <LocationMatch>dan <FilesMatch>masing-masing. Perbedaan pada permukaan cukup jelas:

  • <*Match> arahan mengambil ekspresi reguler sebagai argumen
  • Arahan Non-Match mengambil argumen string atau globe-style-shell sebagai argumen mereka.

Anehnya, arahan non-Match juga dapat diberikan ekspresi reguler sebagai argumen mereka jika didahului oleh '~'. Dengan demikian, dua baris berikut harus identik:

# From the Apache2 docs
<Directory ~ "^/www/[0-9]{3}"> ... </Directory>
<DirectoryMatch "^/www/[0-9]{3}"> ... </DirectoryMatch>

Pertanyaan

Yang ingin saya ketahui adalah apakah ada perbedaan halus atau penting yang perlu diperhatikan bahwa dokumen Apachecore tidak disebutkan. The <DirectoryMatch>bagian tidak menyebutkan satu perbedaan halus:

Kesesuaian

Sebelum 2.3.9 , arahan ini secara implisit diterapkan pada sub-direktori (seperti <Directory>) dan tidak dapat cocok dengan simbol garis akhir ($). Pada 2.3.9 dan yang lebih baru , hanya direktori yang cocok dengan ekspresi yang dipengaruhi oleh arahan terlampir.

Selain itu, saya ingin tahu:

  • Apakah ada perbedaan lain antara arahan Match dan non-Match?
  • Arahan mana yang lebih disukai ketika ekspresi reguler diperlukan?
  • Adakah informasi lain yang Anda rasa relevan?

Catatan

  • <DirectoryMatch>dan <Directory "~">berada pada level gabungan yang sama
  • Meskipun tidak disebutkan secara eksplisit, <Directory "~">dapat menggunakan grup dan referensi yang bernama, seperti <DirectoryMatch>.
ZeroKnight
sumber

Jawaban:

2

Perbedaannya terletak pada jenis parameter yang dibolehkan:

<Directory directory-path> ... </Directory>

vs.

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatchadalah superset, fitur bijak karena Anda akan dapat mengkodekan jalur apa pun sebagai regex. Yang sebaliknya tidak benar.

Directory ~mungkin merupakan penambahan terlambat. Berdasarkan komit yang ditemukan di repositori (komit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc pada November 1996), kasing ini ditambahkan di Apache 1.2

DirectoryMatch kemudian ditambahkan di Apache 1.3 (melakukan a318749e61fda612e883a9ea594459a4517166b8 pada Juli 1997) dengan serangkaian fitur yang lebih kaya.

Dan dokumentasi yang diperbarui dalam komit itu dengan jelas mengatakan Anda harus mendukung versi pertandingan ketika menggunakan regex:

    &lt;Directory ~ &quot;^/www/.*/[0-9]{3}&quot;&gt;
 </pre>

-would match directories in /www/ that consisted of three numbers.<p>
+would match directories in /www/ that consisted of three numbers. In
+Apache 1.3 and later, it is reccomended to use
+<a href="#directorymatch">&lt;DirectoryMatch&gt;</a> instead.<p>

(Pernyataan "disarankan untuk menggunakan DirectoryMatch" ini dihapus kemudian dalam sebuah komitmen pada Agustus 1997)

DirectoryMatchmasih unggul karena Directory ~ditangani hanya setelah Directorypernyataan "normal" , dan DirectoryMatchmemungkinkan Anda untuk mengambil data yang selanjutnya dapat Anda gunakan.

Saat Anda menggunakan regex, saya akan menyukai Matchvarian karena memperjelas bahwa Anda menggunakan ekspresi reguler, dan bukan kasus spesifik dari varian yang tidak cocok. Selain perbedaan kecil di atas, itu tidak akan membuat perbedaan besar.

UPDATE sebenarnya mungkin tidak ada perubahan hasil karena kode melakukan hal yang sama:

static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg)
{

...

    if (!strcmp(cmd->path, "~")) {
        cmd->path = ap_getword_conf(cmd->pool, &arg);
        if (!cmd->path)
            return "<Directory ~ > block must specify a path";
        r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);
        if (!r) {
            return "Regex could not be compiled";
        }
    }
    else if (thiscmd->cmd_data) { /* <DirectoryMatch> */
        r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);
        if (!r) {
            return "Regex could not be compiled";
        }
    }

Jadi panggilan yang sama persis untuk r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);kedua kasus.

Patrick Mevzek
sumber
2
"DirectoryMatch adalah superset" - meskipun OP secara khusus membandingkan <Directory ~dan <DirectoryMatch, tidak <Directory. Sampai Apache 2.3.9, <Directory ~bisa dibilang superset karena mendukung $jangkar regex, sedangkan <DirectoryMatchtidak. (Ini mungkin juga mengapa rekomendasi untuk menggunakan DirectoryMatchdihapus dalam dokumen sebelumnya?)
MrWhite
2
" DirectoryMatchMasih unggul karena Directory ~ditangani hanya setelah Directorypernyataan " normal " , dan DirectoryMatchmemungkinkan Anda untuk mengambil data yang selanjutnya dapat Anda gunakan." - tetapi sebagaimana dicatat oleh OP, arahan ini sama dalam kedua hal ini.
MrWhite
1
Saya setuju bahwa DirectoryMatchlebih mudah dibaca dan oleh karena itu lebih disukai (lebih Directory ~). Meskipun dokumen tidak secara eksplisit menyatakan hal ini, DirectoryMatchdigunakan dalam semua contoh terbaru (mis. Pada halaman Bagian Konfig ) dan Directory ~tidak pernah mendapat penyebutan. Namun, dokumen secara eksplisit menyatakan bahwa nama yang sama LocationMatchdan FilesMatchlebih disukai daripada ~versi yang sesuai dari arahan ini.
MrWhite
@ MrWhite DirectoryMatchtidak mendukung $jangkar sebelum Apache 2.3.9? Komit yang saya temukan terkait dengan Apache 1.2 / 1.3, sejauh ini sebelumnya.
Patrick Mevzek
1
Ya, seperti yang dinyatakan oleh OP (dari 2.4 docs ), sedangkan contoh-contoh awal <Directory ~bahkan termasuk jangkar end-of-string. Ya, saya melihat komitmen tersebut berasal dari 1.2 / 1.3 - penggalian yang bagus! :) Ini juga dinyatakan dalam dokumentasi Apache 1.3 saat DirectoryMatchdiperkenalkan. Ada juga perubahan di Apache 1.3 (dari 1.2) sehubungan dengan bagaimana wadah regex (mis. <Directory ~Dan yang baru saja diperkenalkan <DirectoryMatch) digabung.
MrWhite
1

Apakah ada perbedaan lain antara arahan Match dan non-Match?

Tidak sepenuhnya perbedaan antara dua versi regex ( <Directory ~dan <DirectoryMatch), tetapi beberapa arahan, seperti AllowOverridedan AllowOverrideList, hanya diizinkan dalam wadah polos (non-regex) <Directory>. Jadi, itu tidak termasuk keduanya <Directory ~dan <DirectoryMatch.

Referensi:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

Hanya tersedia di <Directory>bagian
AllowOverride hanya valid di <Directory>bagian yang ditentukan tanpa ekspresi reguler, bukan di <Location>, <DirectoryMatch>atau <Files>bagian.

TuanWhite
sumber