Рейтинг:1

Должен ли я избегать косой черты «/» в RewriteCond?

флаг cn

Нужно ли мне избегать косой черты «/» в RewriteCond?

В настоящее время я пишу следующее правило в .htaccess:

RewriteCond %{QUERY_STRING} rp=/knowledgebase/
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]

Однако это работает только для URL, например https://www.datanumen.com/fi/customer/index.php?rp=/knowledgebase/7/How-to-order-the-full-version-of-DataNumen-Access-Repair.html&language=swedish, но не работает для URL, например https://www.datanumen.com/fi/customer/index.php?rp=%2Fknowledgebase%2F7%2FHow-to-order-the-full-version-of-DataNumen-Access-Repair.html&language=swedish

Итак, я должен изменить правило, как показано ниже:

RewriteCond %{QUERY_STRING} rp=/knowledgebase/ [ИЛИ]
RewriteCond %{QUERY_STRING} rp=%2Fknowledgebase%2F
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]

Но я проверяю https://serverfault.com/a/968916/280923 и он сказал "Косую черту (/) экранировать не нужно.". Так что я в замешательстве.

Если мне нужно принять во внимание все ситуации, то есть экранированную версию и неэкранированную версию '/', тогда должно быть всего 4 комбинации, если я добавлю их все как RewriteCond:

рп=/база знаний/
rp=%2Fбаза знаний%2F
rp=%2Fбаза знаний/
rp=/база знаний%2F
Рейтинг:1
флаг kz

Должен ли я избежать косой черты / в RewriteCond?

Под «экранировать косую черту» вы действительно имеете в виду «должен ли я соответствовать косой черте, закодированной в URL, или нет?». Это полностью зависит от HTTP-запроса к вашему серверу.

Но я проверяю https://serverfault.com/a/968916/280923 и он сказал: «Слэш (/) не нужно экранировать». Так что я в замешательстве.

Связанный вопрос/ответ не имеет отношения к текущей проблеме. Этот вопрос касается экранирования обратной косой черты в директивах / регулярных выражениях Apache, а не URL-адресов с кодировкой URL (или с кодировкой %), с которыми вы имеете дело здесь. Это два очень разных типа методов «убегания» для разных целей.

То, с чем вы имеете дело, - это URL-адреса с кодировкой %. Как URL отображается в HTTP-запросе. Различные части URL-адреса (особенно «путь» и «строка запроса») имеют разные требования к кодированию. Будь то конкретный персонаж потребности быть закодированным с помощью % зависит от того, будет ли он иначе иметь особое значение в этом контексте.

Как определено в RFC3986, косая черта (/) строго не обязательно кодировать % в части строки запроса URL-адреса. Однако функции кодирования URL-адресов (например, в PHP и JavaScript) часто кодируют этот символ с помощью %-кодирования. (Я думаю, что это в значительной степени исторически, поскольку некоторые старые реализации, как сообщается, неправильно обрабатывали незакодированную косую черту - ссылка RFC3986.)

Однако независимо от того, является ли персонаж потребности чтобы быть закодированным в URL (чтобы свести на нет его особое значение), любой символ может быть закодирован в %, и это должно рассматриваться так же, как буквальный (незакодированный) символ.

Нужно ли вам соответствовать / (расшифровано) или %2F (закодировано) зависит от того, закодирован ли этот символ в запросе с помощью %-кодирования.

Ваша проблема в том, что СТРОКА ЗАПРОСА серверная переменная не декодируется %, в отличие от URL-пути, которому соответствует Правило перезаписи шаблон.

Но... нужно ли проверять как %-decoded / и %-закодировано %2F? Предположительно, вы постоянно ссылаетесь только на тот или иной (канонический) URL. Таким образом, любые запросы к неканоническому URL-адресу должны быть введены вручную или ошибочно связаны третьей стороной. Вы получаете запросы к обоим? Каковы последствия отказа от перенаправления неканонического URL-адреса?

В противном случае, да, вам нужно будет проверить оба (и, возможно, все варианты/случаи). Хотя это, скорее всего, будет только /база знаний/ или же %2Fбаза знаний%2F. Но обратите внимание, что это может быть %2F (верхний регистр) или %2f (нижний регистр). Верхний регистр - это просто соглашение. Необходимость проверки смешанной кодировки, такой как %2Fбаза знаний/ должно быть очень редко. Но доведенное до крайности, это то же самое, что и %2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f. Необходимость обработки всех этих вариантов зависит от вероятности получения такого запроса и серьезности несоответствия правил.

Итак, чтобы соответствовать обоим /база знаний/ и %2Fбаза знаний%2F (без учета регистра) вы можете использовать что-то вроде:

RewriteCond %{QUERY_STRING} ^rp=(/|%2[Ff])база знаний(/|%2[Ff])

Вы можете избежать класса символов [Фф] и использовать Северная Каролина флаг, чтобы сделать все сравнение нечувствительным к регистру. Например:

RewriteCond %{QUERY_STRING} ^rp=(/|%2F)база знаний(/|%2F) [NC]

В Apache 2.4 вы можете использовать отменить экранирование () функция в выражении Apache с RewriteCond директива для декодирования URL СТРОКА ЗАПРОСА прежде чем делать сравнение. Однако на самом деле это не поможет вам, поскольку не декодирует косые черты, т.е. %2F или же %2f остается в соответствии с запросом (но любые другие символы %-декодируются). Например:

RewriteCond expr "unescape(%{QUERY_STRING}) =~ m#^rp=(/|%2[Ff])knowledgebase(/|%2[Ff])#"

Это позволит вам соответствовать рп=%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f.


Или, если вы не ожидаете никаких закодированных символов URL в строке запроса, вы можете просто заблокировать любой запрос, который их отправляет! Например, следующее должно быть в верхней части вашей конфигурации:

# Блокировать любой запрос, содержащий символ в кодировке % в строке запроса
RewriteCond %{QUERY_STRING} %[\da-f]{2} [NC]
Правило перезаписи ^ - [R=400]
alancc avatar
флаг cn
Большое тебе спасибо. Теперь я это понимаю.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.