Назад | Перейти на главную страницу

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.

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

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). По умолчанию обработчик, который обрабатывает ответы text / html, не разрешает информацию о пути и неявно запускает 404 (если это не для случайного % - как обсуждалось выше), называя свой заказ ErrorDocument (если определено). Так что RewriteRule директиву в последнем примере можно просто удалить, поскольку Apache все равно вызовет 404 (если вы не переопределите это поведение с помощью AcceptPathInfo).