Sử dụng FallbackResource ngay cả khi thư mục tồn tại


11

Tôi đã thiết lập máy chủ ảo của mình trên Apache 2.4.7 với cấu hình rất cơ bản:

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

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

Bên dưới gốc tài liệu tôi có cấu trúc như sau:

/index.php
/help/readme.txt

Tôi nhận được kết quả sau khi tôi yêu cầu:

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

Có vẻ như sự tồn tại của /help/thư mục đang khiến Apache quay trở lại 404vì không có index.phptrong đó, nhưng tôi hy vọng tất cả các yêu cầu sẽ được gọi /index.phpvà do đó mang lại 200 OKphản hồi.

Tôi không nhớ đây là một vấn đề khi sử dụng mod_rewrite, nhưng tôi thích sử dụng FallbackResourcenếu có thể. Có cách nào để sửa lỗi này?

Cập nhật

Nó hoạt động nếu tôi loại bỏ DirectoryIndexchỉ thị, nhưng nó bị các vấn đề chậm trễ năm giây .

Cập nhật 3

Tôi đang chạy môi trường thử nghiệm sau; cấu trúc thư mục như sau:

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

Nội dung của httpd.conflà:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

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

FallbackResource /index.html
</VirtualHost>

Của tôi config.nicechứa:

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

Để chạy máy chủ:

httpd -X -d /home/user/work/apache-bug/

Và những gì trong cơ thể phản ứng cho /bla?
zerkms

Tôi không chắc là tôi hiểu vấn đề rồi: -S
zerkms

Chỉ để chắc chắn - bạn đang dùng phiên bản nào của Apache?
Jenny D

@JennyD Tôi đang chạy trên 2.4.7.
Jack

Câu trả lời:


8

Tôi cũng tự trả lời điều này, vì tôi khá chắc chắn rằng vấn đề này liên quan đến cách thức mod_dir.choạt động bên trong và tôi nghĩ đó là một lỗi .

Nếu tài nguyên không thể được ánh xạ tới hệ thống tệp cục bộ, chức năng fixup_dflt()sẽ chạy, sử dụng FallbackResourceđể xác định tài liệu nào sẽ được tải thay thế.

Tuy nhiên, khi một tài nguyên có thể được ánh xạ tới hệ thống tệp cục bộ và đó là một thư mục, nó sẽ cố gắng giải quyết tài liệu bằng cách chạy fixup_dir(); hàm này lặp lại danh sách các DirectoryIndexgiá trị cho đến khi tìm thấy tài liệu phù hợp đầu tiên.

Trong trường hợp của tôi, cấu hình có một danh sách các DirectoryIndexgiá trị trống , do đó fixup_dir()sẽ thất bại và 404 được trả về.

Bản vá sau đây hoạt động với tôi ( 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;
}

Nó cơ bản cố gắng fixup_dflt()sau khi fixup_dir()thất bại.

Cập nhật 2015-04-21

Một bản sửa lỗi đã được gửi cho dự án, dự kiến ​​là 2,5; nó cũng có thể được chuyển sang 2.4.

Cập nhật 2015-05-18

Bản sửa lỗi đã được hoàn nguyên vì:

[...] Nó [ít nhất] gây ra FallBackResourceđá trước khi mod_autoindexcó thể đã đá vào.

Tôi vẫn đang cố gắng tìm ra cách để tránh tình huống này.


Tôi muốn nói rằng lỗi là do fixup_dir()bỏ qua FallbackResource.
Ricky Beam

@RickyBeam Có, nhưng về mặt kỹ thuật fixup_dir()không nên biết fixup_dflt(), vì vậy tốt hơn hết là bạn nên sửa nó "cao hơn" :)
Jack

7

Cấu hình của bạn phải chính xác.

Vấn đề, thật kỳ lạ, dường như là mod_deflate .

Sau khi tái tạo thành công cấu hình của bạn ở đây ( không nhận được 404), tôi cũng bị trễ 5 giây. Tuy nhiên, tôi nhận thấy rằng khi UA bỏ qua gzipTiêu đề chấp nhận của nó, trang sẽ được hiển thị / nhận ngay lập tức. Bạn có thể kiểm tra điều này cho chính mình với wget.

Thật thú vị, gỡ lỗi thêm với các stracechương trình cho thấy apache gửi nội dung của bạn FallbackResourceđến ổ cắm của khách hàng mà không có sự khác biệt đáng chú ý về độ trễ cho cả hai trường hợp. Điều này cũng được thấy rõ trên dây, trong đó paket trả lời được gửi từ máy chủ đến máy khách sau Yêu cầu HTTP mà không có bất kỳ độ trễ đáng chú ý nào 1 .

Tuy nhiên, có vẻ như khi sử dụng mod_deflate trong trường hợp này, UA không biết khi nào dữ liệu được gửi bởi máy chủ kết thúc và do đó không hiển thị bất cứ điều gì trước khi kết nối TCP hết 2 và bị máy chủ buộc phải đóng. Điều này tuân thủ HTTP / 1.0, trong đó kết nối đóng biểu thị phần cuối của nội dung.

Đối với HTTP / 1.1 , máy chủ có sẵn các phương tiện khác để báo hiệu kết thúc nội dung - nhưng dường như không có điều gì xảy ra ở đây .

Tuy nhiên, lỗi này ẩn trong mod_dir hoặc mod_deflate, vượt quá thời gian có sẵn của tôi ngay bây giờ. Tôi đã làm cho nó hoạt động hoàn hảo bằng cách vô hiệu hóa nén gzip; như một cách giải quyết cho đến khi vấn đề được khắc phục tốt, bạn có thể vô hiệu hóa chọn lọc gzip.

1 ) Điều này cho chúng ta biết rằng vấn đề không xuất phát từ bộ đệm không được lưu trên máy chủ.
2 ) Theo mặc định, thời gian chờ là 5 giây với apache - đó là nơi 5 giây của bạn đến từ đó.


Cảm ơn. Vấn đề trì hoãn 5s là vấn đề thứ yếu đối với vấn đề chính của tôi, tôi đã cập nhật câu hỏi của mình với cách tái tạo vấn đề cục bộ.
Jack
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.