Что разница между REQUEST_FILENAME и REQUEST_URI в конфигурации apache?

Я не вижу сообщений, в которых обсуждаются различия между REQUEST_URI и REQUEST_FILENAME , хотя я вижу во многих сообщениях они используются взаимозаменяемо.

Я включил журнал mod_rewrite ( LogLevel alert rewrite: trace8 ), заменил REQUEST_FILENAME на REQUEST_FILENAME REQUEST_FILEN ], просмотрел журнал перезаписи в каждой конфигурации, и процесс перезаписи точно такой же.

Итак, мой вопрос: :

Они одинаковы в 99% случаев?

Я не сказал 100% потому что я вижу в документе ( https://httpd.apache.org/docs/current/mod/mod_rewrite.html ) упоминание об исключении для REQUEST_URI , относящемся к так называемому AcceptPathInfo .

REQUEST_FILENAME

Полный путь локальной файловой системы к файлу или сценарию. соответствие запросу, если это уже было определено сервер во время ссылки REQUEST_FILENAME . В противном случае, например, при использовании в контексте виртуального хоста то же значение, что и REQUEST_URI . В зависимости от значения AcceptPathInfo сервер может иметь только использовали некоторые ведущие компоненты REQUEST_URI для сопоставления запроса с файл.

На самом деле мне трудно понять все определение, а не только последнее предложение.


Я использую REQUEST_FILENAME и REQUEST_URI в основном между .

Мой настройки:

<VirtualHost *:443>
        ServerAdmin admin@exmaple.com
        DocumentRoot /var/www/example.com/public_html
        ServerName example.com
        ServerAlias www.example.com



        LogLevel alert rewrite:trace8
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

RewriteEngine On
#RewriteCond %{REQUEST_URI} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule (.*) /tq_info.php?p=%{REQUSET_URI}

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/.*\.php$
RewriteCond %{REQUEST_FILENAME} !/admin/.*
RewriteRule (.*) /index.php/$1 [L]
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
0
задан 12 July 2020 в 06:42
2 ответа

Они очень разные и служат разным целям.

REQUEST_URI — это компонент пути URI в запросе. Например, /tq_info.php.

REQUEST_FILENAME является результатом попытки найти файл в локальной файловой системе путем применения пути URI к корню документа или любого псевдонима, который мог быть определен. Таким образом, если файл существует, для него будет установлено значение /var/www/example.com/public_html/tq_info.php. Он используется для поиска файла в файловой системе. Он устанавливается равным REQUEST_URI только в том случае, если в файловой системе нет файла. В этом случае запрос будет передан обработчику 404 или вышестоящему веб-приложению, если вы определили его в конфигурации своего веб-сервера, которое соответствует пути URI.

Когда вы выбираете, какой из них использовать, вам нужно подумать о том, пытаетесь ли вы работать с компонентом пути URI или с путем соответствующего файла в вашей файловой системе.

0
ответ дан 12 July 2020 в 03:50

Я опаздываю на вечеринку, но кое-что проясню:

REQUEST_URI, как Майкл Хэмптон написал, всегда содержит компонент пути запрошенного URI. Это означает, что параметры запроса (например, ?a=b) удаляются из URI запроса.

REQUEST_FILENAME — зверь.

В лучшем случае он будет содержать сопоставление пути локальной файловой системы с тем, что было запрошено, и это будет точно %{DOCUMENT_ROOT}%{REQUEST_URI}. Однако это не обязательно. Если %{REQUEST_URI} сопоставляется с псевдонимом, он будет прозрачно перенаправлен, поэтому %{REQUEST_FILENAME} тоже будет другим. Это также верно для цепочки перенаправлений, например //tricked/you, причем последний путь действительно существует (относительно корня документа). Можно возразить, что это промежуточный шаг, который можно игнорировать, но цепочка возможна.

Затем параметр конфигурации AcceptPathInfo изменяет способ сопоставления URI запросов с файлами. Если установлено значение на, сервер также сканирует файлы на наличие вложенных путей и предоставляет конечные данные в %{PATH_INFO}. В таком случае только часть %{REQUEST_URI} может использоваться для сопоставления пути к расположению в файловой системе. Расширяя приведенный выше пример, если /tricked/you ссылается на правильный файл, %{REQUEST_URI} из /tricked/you/and/then/some/more позволит httpd сопоставить запрос с тем, что /tricked/you сопоставили бы и выставит /and/then/some/more как %{PATH_INFO}, что означает, что %{REQUEST_FILENAME} в конечном итоге будет чем-то вроде %{DOCUMENT_ROOT}/tricked/you.

Наконец, от контекста файла %{REQUEST_FILENAME} уже расширен до фактического пути к файловой системе или все еще установлено значение %{REQUEST_URI}. его использование. В контексте VirtualHost, который вы используете, это никогда не будет сопоставленным путем файловой системы — главным образом потому, что эта кодовая точка находится перед фактической точкой сопоставления в пути кода. К сожалению, нет простого способа узнать, мог ли httpd уже сопоставить (часть) %{REQUEST_URI} с местоположением в файловой системе или нет, кроме просмотра исходного кода и надежды, что выполнение путь не изменится неожиданно.

Однако есть несколько предположений, которые вы можете сделать с уверенностью:

  • Контексты VirtualHost будут видеть только несопоставленные значения
  • Запрос этой переменной в сценарии, являющемся частью корня документа, всегда будет возвращать сопоставленный путь (поскольку как иначе httpd сможет выполнить сценарий, если его местоположение не было заранее сопоставлено?)

Все остальное методом проб и ошибок. В частности, %{REQUEST_FILENAME} не нужно отображать в любом случайно выполняемом сценарии. Подумайте об обертках, которые фактически определяют, какой файл обслуживать или выполнять, когда он установлен в качестве обработчиков.

1
ответ дан 5 May 2021 в 08:18

Теги

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