RFC2396 - что такое допустимый сегмент пути? - PullRequest
2 голосов
/ 30 марта 2011

проблемная зона

Мне нужно определить, является ли конкретный сегмент пути допустимым для RFC2396 . В спецификации сказано:

path_segments = segment *( "/" segment )
segment       = *pchar *( ";" param )
param         = *pchar
pchar         = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
unreserved    = alphanum | mark
mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
escaped       = "%" hex hex
hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
                        "a" | "b" | "c" | "d" | "e" | "f"

Так, например, /foo является допустимым сегментом пути, но /fo?o не из-за не экранированного ?. Чтобы исправить приведенный выше пример, сегмент пути должен быть записан как /fo%3Fo.

Спецификация, однако, определяет только действительность URI, которые поступают на сервер (подумайте: напечатано в строке URL).

На самом деле мне нужно проверить, является ли неэкранированный сегмент пути действительным. Продолжая приведенный выше пример, /fo?o будет допустимым ресурсом, так как ? - это то, что вы получаете при удалении %3F.

Это также означает, что URL http://foo.com/first/sec%2fond будет преобразован в два неэкранированных сегмента пути, /first и /sec/ond, и последний должен рассматриваться не только как один сегмент, а не как два отдельных но также синтаксически допустимы (как неэкранированный сегмент пути).

Вопросы

  • правильно ли я понимаю спецификацию?
  • Кто-нибудь может предложить валидатор Java для неэкранированных сегментов пути?
  • Кто-нибудь может предложить нетривиальный случай неудачи?
  • как насчет символов выше U + 00FF, их нельзя использовать в сегментах пути? Я думал, что они поддерживаются, по крайней мере, в доменных именах.

РЕДАКТИРОВАТЬ: как правильно указал Майк, RFC3986 устарел RFC2396. В любом случае, я считаю, что новый RFC обрабатывает больше случаев, чем старый (и не делает некоторые сегменты пути нелегитимными), поэтому применяются те же вопросы.

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

Так, например, / foo является допустимым сегментом пути, но / fo? O не из-за неэкранированного?. Чтобы исправить приведенный выше пример, сегмент пути должен быть записан как /fo%3Fo.

Корректное

Это также означает, что URL http://foo.com/first/sec%2fond будет преобразован в два неэкранированных сегмента пути, / first и / sec / ond, и последний должен рассматриваться не только как один сегмент, а не как два отдельных, но также синтаксически допустим (как сегмент неэкранированного пути).

Правильно. Хотя есть много реализаций, которые ошибаются.

как насчет символов выше U + 00FF, их нельзя использовать в сегментах пути? Я думал, что они поддерживаются, по крайней мере, в доменных именах.

URI экранирует (% hex hex) байты кодирования. Не кодовые точки. Вам нужно знать кодировку URL. Например, если кодировка UTF-8, тогда кодовая точка U + 1234 кодируется как %E1%88%B4.

Процентные экранирования не допускаются в доменных именах. Международные доменные имена см. RFC 3492 .

.
2 голосов
/ 30 марта 2011

Я бы интерпретировал спецификацию так же, как вы; то есть sec%2Fond является одним сегментом пути. (Но & mdash; любой, кто создает URI с таким сегментом, должен быть строго наказан!)

Проблема, с которой вы боретесь, состоит в том, что процесс выхода из строя - это lossey; вы не можете совершить обратную передачу из экранированного URI в не экранированный String и обратно в исходный экранированный URI. Там нет никакого способа обойти это; Вы должны получить экранированный URI, прежде чем любая «полезная» обработка отбросит эту важную информацию.

Вы можете прочитать & sect; 2.1 для получения подробной информации об обработке символов, не относящихся к ASCII, но я понимаю, что правила экранирования в RFC 2396 применяются к строке октетов (байтов) после строки символов URI был закодирован символом. Как выполняется кодирование символов, может быть указано схемой; нет общего метода.

...