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

Как Apache обрабатывает путь с URL-адресом, закодированным в процентах?

Я столкнулся с неожиданным случаем, когда Apache выдавал мне ошибку 404 вместо того, чтобы позволить mod_rewrite обрабатывать путь, когда одна из частей пути, закодированных в процентах, сама была URL-адресом HTTP.

Например:

GET /myfolder/http%3A%2F%2Flocalhost%2Fnotify HTTP/1.0

У меня очень простое правило /myfolder/.htaccess файл, который отправляет все это не файл в /myfolder/ к сценарию. Он отлично работает с другими значениями, закодированными в процентах, но в этом случае Apache никогда не обрабатывает RewriteRule из .htaccess файл. Я могу дважды закодировать значение в качестве обходного пути, но кажется, что Apache все еще должен обрабатывать фазы mod_rewrite. Я предполагаю, что URL-адрес будет просто входным параметром скрипта.

Вот соответствующие директивы mod_rewrite в /myfolder/.htaccess:

RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule .* ./script-the-world.php

Правила перезаписи НЕ обрабатываются. В конфигурации сервера у меня есть RewriteLogLevel 5и т. д., и tail -f /var/log/http/rewrite.log показывает все мои запросы /myfolder/ переписывается ... кроме упомянутого выше. Я хочу сказать, что что-то внутреннее происходит в описанном выше частном случае, но я понятия не имею, что это такое. Я надеюсь, что кто-то может знать о другом модуле, который мешает тому, что я пытаюсь выполнить.

Это Apache 2.2.16.

Вам нужно будет включить AllowEncodedSlashes, что приведет к тому, что Apache разрешит URL-адреса с %2F и %5C в них вместо того, чтобы выдавать 404. Вы, конечно, должны убедиться, что ваш PHP-скрипт правильно обрабатывает декодирование URL, поскольку это не обязанность Apache.

Поскольку этому вопросу уже 9 лет, но проблема все еще актуальна, я подумал, что дам более полный ответ о том, как ее решить.

Включить %F2 и %5C на ваших путях без получения ошибки 404, вам нужно добавить следующую строку в конфигурацию apache2:

AllowEncodedSlashes NoDecode

Из Apache2.4 документация:

В AllowEncodedSlashes Директива разрешает URL-адреса, содержащие закодированные разделители путей (%2F для / и дополнительно %5C для \ в соответствующих системах) для использования в информации о пути.

Со значением по умолчанию, Off, такие URL-адреса отклоняются с ошибкой 404 (не найдено).

Со значением Onтакие URL-адреса принимаются, а закодированные косые черты декодируются, как и все другие закодированные символы.

Со значением NoDecodeтакие URL-адреса принимаются, но закодированные слэши не декодируются, а остаются в закодированном состоянии.

Так как NoDecode был представлен в 2.4, если вы все еще используете Apache2.2, вы можете установить значение On вместо. Будьте осторожны, их функциональность не одинакова. Как указано в документации, NoDecode не будет декодировать строку и оставит ее как есть, в то время как On воля.

То, что никто не объяснил (по крайней мере, мне), был где Я должен применить это значение. Есть некоторые ссылки на httpd.conf файл, но удачи в поиске этого файла, если вы используете Apache2 в Debian. В Ubuntu файл называется apache2.conf. А если добавить строчку в apache2.conf файла, вы, вероятно, не увидите больших изменений.

Причина этого в том, что, как вы, возможно, знаете, ваши файлы конфигурации будут включать разделы для виртуальный хост. И конфиги внутри каждого из них <VirtualHost> section применяются после соответствующих разделов вне определения виртуального хоста.

Это позволяет виртуальным хостам переопределять конфигурацию основного сервера. Что обычно хорошо. За исключением этого контекста, когда он технически отменяет AllowEncodedSlashes директива (и верните ее к значению по умолчанию Off), если вы явно не укажете в каждом <VirtualHost> раздел, какое значение должно быть.

Таким образом, если вы хотите решить эту проблему, сделайте следующее (по крайней мере, на Ubuntu):

  1. Перейти к /etc/apache2/sites-enabled
  2. Открывайте каждый найденный файл.
  3. Добавить AllowEncodedSlashes NoDecode внутри каждый <VirtualHost> раздел, который имеет отношение к вам.
  4. Сохраните файл.
  5. Перезагрузите apache2: sudo systemctl restart apache2.