Sự khác biệt rõ ràng giữa các lệnh <Directory> và <DirectoryMatch> (và các lệnh <* Match> khác)


8

Lời nói đầu

Tôi rất là một người mới về máy chủ web. Tôi đang thiết lập một máy chủ Apache2 và hiện đang xem qua tài liệu này.

Tôi nhận thấy rằng <Directory>, <Location><Files>chỉ mỗi người đều có một tương ứng với <*Match>chỉ thị: <DirectoryMatch>, <LocationMatch><FilesMatch>tương ứng. Sự khác biệt trên bề mặt là đủ rõ ràng:

  • <*Match> các chỉ thị lấy một biểu thức chính quy làm đối số
  • Các chỉ thị không khớp lấy một chuỗi đơn giản hoặc toàn cục kiểu vỏ làm đối số của chúng.

Thật kỳ lạ, các chỉ thị không khớp cũng có thể được đưa ra một biểu thức chính quy làm đối số của chúng nếu nó được đặt trước '~'. Do đó, hai dòng sau phải giống hệt nhau:

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

Câu hỏi

Điều tôi muốn biết là liệu có bất kỳ sự khác biệt tinh tế hay quan trọng nào để nhận thức được rằng các coretài liệu của Apache không đề cập đến hay không. Các <DirectoryMatch>phần không đề cập đến một sự khác biệt tinh tế:

Khả năng tương thích

Trước 2.3.9 , lệnh này được áp dụng ngầm cho các thư mục con (như <Directory>) và không thể khớp với ký hiệu cuối dòng ($). Trong 2.3.9 trở lên , chỉ các thư mục phù hợp với biểu thức bị ảnh hưởng bởi các chỉ thị kèm theo.

Ngoài ra, tôi muốn biết:

  • Có sự khác biệt nào khác giữa các chỉ thị Trận đấu và Không khớp không?
  • Lệnh nào thích hợp hơn khi cần một biểu thức chính quy?
  • Bất kỳ thông tin khác bạn cảm thấy là thích hợp?

Ghi chú

  • <DirectoryMatch><Directory "~">ở cùng cấp độ hợp nhất
  • Mặc dù không được đề cập rõ ràng, <Directory "~">có thể sử dụng các nhóm được đặt tên và phản hồi, giống như <DirectoryMatch>.

Câu trả lời:


2

Sự khác biệt là trong loại tham số được phép:

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

đấu với

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatchlà một superset, tính năng khôn ngoan vì bạn sẽ có thể mã hóa bất kỳ đường dẫn nào dưới dạng regex. Điều ngược lại là không đúng sự thật.

Directory ~có lẽ là một bổ sung muộn. Dựa trên một cam kết được tìm thấy trong kho lưu trữ (cam kết 07b82419b59d1bb7ba8860b86a2d381d5d1090bc vào tháng 11 năm 1996), trường hợp này đã được thêm vào trong Apache 1.2

DirectoryMatch sau đó đã được thêm vào Apache 1.3 (cam kết a318749e61fda612e883a9ea594459a4517166b8 vào tháng 7 năm 1997) với bộ tính năng phong phú hơn.

Và tài liệu được cập nhật trong cam kết đó nói rõ rằng bạn nên ưu tiên phiên bản phù hợp khi sử dụng 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>

(câu lệnh "khuyến nghị sử dụng DirectoryMatch" này đã bị xóa sau đó trong một cam kết vào tháng 8 năm 1997)

DirectoryMatchvẫn vượt trội vì Directory ~chỉ được xử lý sau các Directorycâu lệnh "bình thường" và DirectoryMatchcho phép bạn thu thập dữ liệu mà sau đó bạn có thể sử dụng.

Khi bạn đang sử dụng Matchbiểu thức chính quy , tôi sẽ ưu tiên biến thể vì nó làm rõ hơn rằng bạn đang sử dụng biểu thức chính quy và không phải là trường hợp cụ thể của biến thể không khớp. Bên cạnh những khác biệt nhỏ ở trên, tuy nhiên nó sẽ không tạo ra sự khác biệt lớn.

CẬP NHẬT trong thực tế có lẽ không có thay đổi nào trong kết quả do mã thực hiện tương tự:

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";
        }
    }

Vì vậy, chính xác cùng một cuộc gọi đến r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);trong cả hai trường hợp.


2
"DirectoryMatch là một superset" - mặc dù OP đặc biệt so sánh <Directory ~<DirectoryMatchkhông <Directory. Cho đến Apache 2.3.9, <Directory ~được cho là superset vì nó hỗ trợ $neo regex, trong khi đó <DirectoryMatchthì không. (Điều này cũng có thể là lý do tại sao khuyến nghị sử dụng DirectoryMatchđã bị xóa trong các tài liệu trước đó?)
MrWhite 22/03/18

2
" DirectoryMatchvẫn vượt trội vì Directory ~chỉ được xử lý sau các Directorycâu lệnh " bình thường " và DirectoryMatchcho phép bạn thu thập dữ liệu mà sau đó bạn có thể sử dụng." - nhưng theo ghi nhận của OP, các chỉ thị này giống nhau ở cả hai khía cạnh này.
MrWhite

1
Tôi đồng ý rằng DirectoryMatchnó dễ đọc hơn và do đó thích hợp hơn (hơn Directory ~). Trong khi các tài liệu không nêu rõ điều này, DirectoryMatchđược sử dụng trong tất cả các ví dụ gần đây (ví dụ: trên trang Cấu hình ) và Directory ~không bao giờ được đề cập. Tuy nhiên, các tài liệu nói rõ rằng tên tương tự LocationMatchFilesMatchđược ưu tiên hơn ~phiên bản tương ứng của các chỉ thị này.
MrWhite

@MrWhite DirectoryMatchkhông hỗ trợ $neo trước Apache 2.3.9? Các cam kết tôi tìm thấy có liên quan đến Apache 1.2 / 1.3, cho đến nay.
Patrick Mevzek

1
Có, như đã nêu của OP (từ 2,4 tài liệu ), trong khi các ví dụ ban đầu <Directory ~thậm chí bao gồm cả neo cuối chuỗi. Vâng, tôi thấy những cam kết đó là từ 1.2 / 1.3 - đào tốt! :) Nó cũng được nêu trong tài liệu Apache 1.3 khi DirectoryMatchđược giới thiệu. Cũng có những thay đổi trong Apache 1.3 (từ 1.2) liên quan đến cách các thùng chứa regex (nghĩa là <Directory ~và vừa được giới thiệu <DirectoryMatch) đã được hợp nhất.
MrWhite

1

Có sự khác biệt nào khác giữa các chỉ thị Trận đấu và Không khớp không?

Không hoàn toàn là một sự khác biệt giữa hai phiên bản regex ( <Directory ~<DirectoryMatch), nhưng một số chỉ thị, chẳng hạn như AllowOverrideAllowOverrideList, chỉ được phép trong một <Directory>thùng chứa đơn giản (không phải regex) . Vì vậy, loại trừ cả hai <Directory ~<DirectoryMatch.

Tham khảo:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

Chỉ có sẵn trong <Directory>phần
AllowOverride chỉ có hiệu lực trong <Directory>phần quy định mà không biểu thức thông thường, không phải trong <Location>, <DirectoryMatch>hoặc <Files>phần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.