Является косой чертой ( "/" ), эквивалентной закодированной косой чертой ( "% 2F" ) в части пути HTTP-URL

У меня есть сайт, который обрабатывает "/" и "% 2F" в части пути (а не в строке запроса) URL-адреса по-разному. Это плохо, что нужно делать в соответствии с RFC или реальным миром?

Я спрашиваю, потому что я постоянно испытываю небольшие сюрпризы в используемой веб-инфраструктуре (Ruby on Rails), а также в слоях ниже (Passenger, Apache, например, мне пришлось включить "ALLOW_ENCODED_SLASHES" для Apache). Я теперь склоняюсь к тому, чтобы полностью избавиться от закодированных косечек, но мне интересно, должен ли я записывать отчеты об ошибках, где я вижу странное поведение, связанное с закодированными косыми чертами.

Что касается того, почему у меня есть кодированные косые черты, в основном у меня есть такие маршруты, как это:

:controller/:foo/:bar

где: foo - это что-то вроде пути, который может содержать слэши. Я подумал, что наиболее простой задачей было бы просто вывести URL foo, чтобы косые черты игнорировались механизмом маршрутизации. Теперь у меня возникают сомнения, и довольно ясно, что фреймворки на самом деле не поддерживают это, но, согласно RFC, неправильно это делать?

Вот некоторая информация, которую я собрал:

RFC 1738 (URL):

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

RFC 2396 (URI):

Эти символы называются "зарезервированными", поскольку их использование в компоненте URI ограничено их зарезервированной целью. Если данные для компонента URI будут конфликтовать с зарезервированной целью, тогда конфликтующие данные должны быть экранированы перед формированием URI.

(может ли экранирование означать нечто иное, чем кодирование зарезервированного символа?)

RFC 2616 (HTTP/1.1):

Символы, отличные от символов в "зарезервированных" и "небезопасных" наборах (см. RFC 2396 [42]), эквивалентны их "% HEX HEX".

Существует также этот отчет об ошибках для Rails, где они, похоже, ожидают, что закодированная косая черта будет вести себя по-другому:

Правильно, я ожидаю разные результаты, потому что они указывают на разные ресурсы.

Он ищет литеральный файл 'foo/bar' в корневом каталоге. Неэкранированная версия ищет файловую панель в каталоге foo.

Из RFC ясно, что raw vs. encoded является эквивалентом для безоговорочных символов, но какова история зарезервированных символов?

Ответ 1

Из собранных вами данных я бы сказал, что закодированные "/" в uri означают, что они снова будут отображаться как "/" на уровне приложения /cgi.

Чтобы сказать, что если вы используете apache с mod_rewrite, например, он не будет соответствовать шаблону, ожидающему слэш в URI с закодированными косыми чертами. Однако, как только соответствующий модуль /cgi/... вызывается для обработки запроса, он выполняет его для декодирования и, например, извлекает параметр, включая косые черты, в качестве первого компонента URI.

Если ваше приложение затем использует эти данные для извлечения файла (чье имя файла содержит косую черту), возможно, это плохо.

Подводя итог, я считаю совершенно нормальным видеть разницу в поведении в "/" или "% 2F", поскольку их интерпретация будет выполняться на разных уровнях.

Ответ 2

У меня также есть сайт с многочисленными URL-адресами с символами urlencoded. Я нахожу, что многие веб-API (в том числе инструменты Google для веб-мастеров и несколько модулей Drupal) обходятся по URL-адресам. Многие API-интерфейсы автоматически декодируют URL-адреса в какой-то момент своего процесса, а затем используют результат как URL-адрес или HTML. Когда я нахожу одну из этих проблем, я обычно дважды кодирую результаты (что превращает% 2f в% 252f) для этого API. Однако это нарушит другие API, которые не ожидают двойного кодирования, поэтому это не универсальное решение.

Лично я избавляюсь от как можно большего числа специальных символов в своих URL-адресах.

Кроме того, я использую номера id в своих URL-адресах, которые не зависят от urldecoding:

example.com/blog/my-amazing-blog%2fstory/yesterday

становится:

example.com/blog/12354/my-amazing-blog%2fstory/yesterday

в этом случае мой код использует только 12354 для поиска статьи, а остальная часть URL-адреса игнорируется моей системой (но по-прежнему используется для SEO). Кроме того, этот номер должен появиться ПЕРЕД неиспользованным компонентом URL. Таким образом, URL-адрес будет работать, даже если% 2f будет неправильно декодироваться.

Кроме того, не забудьте использовать канонические теги, чтобы ошибки URL не переводились в дублированный контент.

Ответ 3

История %2F vs / заключалась в том, что согласно первоначальной рекомендации W3C, слэша "должна подразумевать иерархическую структуру":

Пример 2

URI

http://www.w3.org/albert/bertram/marie-claude

и

http://www.w3.org/albert/bertram%2Fmarie-claude

НЕ идентичны, так как во втором случае закодированная косая черта не имеют иерархическое значение.

Ответ 5

Что делать, если :foo в своей естественной форме содержит косые черты? Вы бы этого не хотели. Разве это не отличие, которое эта рекомендация пытается сохранить? Он специально отмечает,

Сходство с условными обозначениями имен файлов операционной системы unix и других дисковых систем должно рассматриваться как чисто случайное и не должно быть указано, что URI следует интерпретировать как имена файлов.

Если кто-то создавал онлайновый интерфейс для программы резервного копирования и хотел выразить путь как часть пути URL, было бы целесообразно кодировать косые черты в пути к файлу, так как это не является частью иерархия ресурса - и, что более важно, маршрут. /backups/2016-07-28content//home/dan/ теряет корень файловой системы в двойной косой чертой. Выйти из косой черты - это подходящий способ отличить, как я ее прочитал.