У меня есть некоторые веб-сервисы, которые я пишу, и я стараюсь быть как RESTful, насколько это возможно. Я размещаю эти веб-службы, используя HTTPHandler, работающий внутри IIS/ASP.NET/SharePoint.
Большинство моих служб ожидают HTTP GET. У меня есть два из них, которые просто возвращают некоторые данные (т.е. Запрос) и будут Idempotent, но параметры могут быть несколько сложный. Оба они могут включать символы в параметры службы, которые не разрешены, по крайней мере, для части PATH URL.
Используя IIS, ASP.NET и SharePoint, я обнаружил, что следующие символы в пути URL-адреса даже не попадают в мой HttpHandler, даже если Url закодирован (запрос взрывается, и у меня нет простого управления над этим):
- % (% 25)
- & (% 26)
- * (% 2a, но не Url encode)
- + (% 2b)
- : (% 3a)
- < (% 3c)
-
(% 3e)
Следующие символы попали в мой HttpHandler, но UriTemplate не смог обработать их правильно, даже если Url был закодирован:
-
(% 23)
- . (% 2e, но не Url encode, UriTemplate удалил ".", Если is является последним символом перед /)
- ? (% 3f)
- /(% 2f - UriTemplate не работает по понятным причинам, даже если UrlEncoded)
- \(% 5c)
Итак, я был несколько тщательным, но мне нужно проверить эти закодированные url символы в строке запроса. Похоже, что это будет работать по большей части там.
В одной из моих служб специальные символы, которые являются параметрами, являются семантически частью запроса/фильтра (на самом деле поисковыми запросами для службы поиска), но в другом они не являются частью части запроса/фильтра, поэтому в идеале они являются частью пути, а не строки запроса.
Мой вопрос: какой вариант лучше? Вот некоторые из которых я знаю:
-
Использовать HTTP GET и строку запроса. Все, что может использовать специальные символы, должно быть в строке запроса и Url Encoded. Здесь я склоняюсь, но меня беспокоят чрезвычайно длинные строки запросов (IE имеет ограничение 2083)
-
Использовать кодировку HTTP GET и base64 в пути. Используйте Измененный Base64 для URL для любого параметры, которые могут использовать специальные символы и сохранять их как часть пути, если это необходимо. Я пробовал это, и он работает, но это отвратительно. Все еще беспокоит чрезвычайно длинные строки запросов.
-
Использовать HTTP POST и тело сообщения. Все, что может использовать специальные символы, должно быть в теле запроса. Похоже на достойное решение, но сообщения понимаются как не Idempotent и (я думал), как правило, предназначенный для изменений (тогда как здесь не происходит никаких изменений).
-
Использовать HTTP GET и тело сообщения. Все, что может использовать специальные символы, должно быть в теле запроса. Это выглядит как плохая идея в соответствии с SO: HTTP GET с телом запроса и Roy Fielding.
-
Используйте комбинацию # 3 и # 1 или # 2 выше в зависимости от того, насколько большой может быть запрос.
-
Другое???
Обратите внимание, что в некоторых случаях я могу изменить ситуацию, чтобы предотвратить специальные символы (и я могу это сделать), но я не смогу сделать это во всех случаях.
Что касается длины URI, RFC2616 Sec3.2.1 говорит следующее:
Протокол HTTP не устанавливает априорного ограничения длины URI. Серверы ДОЛЖНЫ иметь возможность обрабатывать URI любого ресурса, который они обслуживают, и СЛЕДУЕТ иметь возможность обрабатывать URI неограниченной длины, если они предоставляют формы на основе GET, которые могут генерировать такие URI. Сервер ДОЛЖЕН возвращать 414 (Request-URI Too Long) статус, если URI больше, чем сервер может обрабатывать (см. Раздел 10.4.15).
Note: Servers ought to be cautious about depending on URI lengths
above 255 bytes, because some older client or proxy
implementations might not properly support these lengths.
Кроме того, Максимальная длина URL-адреса составляет 2,083 символа в Internet Explorer.
Связанный: Как передать сложные запросы в REST?