Apache HTTPD 2.4.x: Как «направлять» пользователей на настраиваемую страницу ошибок, если в URL / URI присутствуют определенные символы?

, поэтому у меня есть эта конфигурация apache, в которой я пытаюсь «переписать» пользователей на пользовательская страница ошибки, но она не работает. Я ввел http: //localhost/index.html/ddgdg%: sdsdfs в браузере и не получил свою страницу с ошибкой.

Я могу просмотреть настраиваемую страницу с ошибкой, напрямую введя ее URL в браузере ( http: //localhost/my-error.html ).

Есть идеи, что я делаю неправильно?


мой полный httpd.conf : ссылка на httpd.conf


мои изменения в httpd.conf по умолчанию (мне также пришлось раскомментировать LoadModule для mod_rewrite.so)

RewriteEngine On
LogLevel alert rewrite:info
#if invalid characters are present in the URI, display 404 page
RewriteCond %{REQUEST_URI} ^\/.+[:%].+  
RewriteRule "^/$" "http://%{SERVER_NAME}/my-error.html" [L,R=301]

содержимое пользовательской страницы ошибок

$ cat /Library/WebServer/Documents/my-error.html 
<html><body><h1>404 error here</h1></body></html>

версии apache

$ apachectl -v
Server version: Apache/2.4.34 (Unix)
Server built:   Feb 22 2019 20:20:11

edit1: В данный момент работает macOS Mojave, но через некоторое время будет настроена виртуальная машина Ubuntu.

1
задан 23 July 2019 в 22:49
1 ответ

Здесь происходит несколько разных проблем ...

 http: //localhost/index.html/ddgdg%: sdsdfs
 

На самом деле вы не указали, какой ответ вы получаете, а только что не происходит . Однако из-за случайного % (не предшествующего октету с шестнадцатеричным кодированием) этот URL строго недействителен, и я ожидаю, что Apache ответит 400 Bad Request . Единственный способ изменить это - создать собственный документ с ошибкой 400, в котором вы проверяете запрошенный URL и настраиваете ответ. Например:

ErrorDocument 400 /my-error.html

Если бы не случайный % , вы могли бы перехватить этот запрос с помощью mod_rewrite и соответствующим образом перенаправить. Однако ваше RewriteRule проверяет наличие пустого URL-пути (например, «^ / $» ),тогда как запрошенный URL-адрес в вашем примере далеко не пустой (например, /index.html/ddgdg%:sdsdfs ), поэтому директива RewriteRule никогда не будет соответствовать URL-адресу вашего примера. Чтобы проверить % или : в любом месте URL-пути и выполнить перенаправление, вы можете сделать что-то вроде следующего:

# Checks for a "%" or ":" in the URL-path
RewriteRule [%:] /my-error.html [L,R=302]

Но обратите внимание, что URL-путь соответствует RewriteRule шаблон (а также серверная переменная REQUEST_URI ) уже% -декодирован, поэтому он будет соответствовать только URL-адресам, где специальные символы были закодированы дважды (редко). (Как отмечалось выше, в противном случае случайный % , скорее всего, сгенерирует ответ 400 до того, как mod_rewrite сможет обработать запрос.)

Я также хотел бы спросить, почему вы хотите " перенаправить "в пользовательский документ об ошибке (например, my-error.html ) и не обслуживать его напрямую? Перенаправление имеет ряд недостатков: ответ 3xx отправлен клиенту, потеря информации об URL-адресе, вызвавшем ошибку, удвоение количества запросов к вашему серверу и т. Д.

Вы можете внутренне переписать запрос на /my-error.html , вместо перенаправления, просто сняв флаг R . Например:

RewriteRule [%:] /my-error.html [L]

Но если вы вручную не установите статус HTTP в my-error.html , то пользователь увидит ответ 200 OK , что нежелательно.

] ИЛИ (желательно) создать пользовательский 404 (который выглядит как то, что вы пытаетесь сделать) и запустить его вместо этого. Например:

ErrorDocument 404 /my-error.html

RewriteRule [%:] - [R=404]

Apache затем устанавливает статус HTTP-ответа «404 Not Found».

Однако вам, вероятно, здесь вообще не нужно использовать mod_rewrite. В вашем примере URL все после index.html в URL-пути, а именно / ddgdg%: sdsdfs , представляет собой дополнительную информацию о пути (также известную как path-info / PATH_INFO ). По умолчанию обработчик, который обрабатывает ответы text / html, не разрешает информацию о пути и неявно запускает 404 (если это не для случайного % - как обсуждалось выше), вызывая ваш собственный ErrorDocument (если определено). Итак, директиву RewriteRule в последнем примере можно просто удалить, поскольку Apache все равно вызовет 404 (если вы не переопределите это поведение с помощью AcceptPathInfo ).

1
ответ дан 3 December 2019 в 23:02

Теги

Похожие вопросы