Pull to refresh

Comments 18

влечёт за собой запрет GET и DELETE иметь тело запроса (поскольку этому телу невозможно приписать никакой осмысленной роли).

Вообще-то стандарт HTTP нигде не запрещает GET иметь тело, в теле GET можно передать фильтры в виде объекта, а не насиловать query часть URL.

Все реализации HTTP клиентов\серверов делятся на тех кто читал спеку и делал по спеке и тех кто делал по наитию сердца. От нечитающих спеки нам приехали уязвимости HTTP Request Split - Content-Length, Content-Encoding: chunked, HTTP Header Injection etc.

Hidden text

не глядя моё на бухтение статья понравилась, автор молодец.

В стандарте написано ровно то же, что и я написал ;)

Although request message framing is independent of the method used,
content received in a GET request has no generally defined semantics [...] A client SHOULD NOT generate content in a GET request unless it is
made directly to an origin server that has previously indicated,
in or out of band, that such a request has a purpose and will be adequately
supported. An origin server SHOULD NOT rely on private agreements to
receive content, since participants in HTTP communication are often
unaware of intermediaries along the request chain.

Что касается передачи доп. параметров в немодицифицирующем запросе, то для этого разрабатывают новый метод QUERY (хотя в целом никто не запрещал использовать для этой цели SEARCH). Будет разобрано в следующей главе.

В стандарте написано ровно то же, что и я написал ;)

Можно ссылку на стандарт. В RFC-2616 такого нет.

4.3 Message Body

The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.

Т.е. послать можно, сервер не должен придавать этому значения. А в более поздней редакции RFC 7231

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

Слать можно, но работать не будет т.к. много программистов неправильно реализовали спеку.

Ссылка на стандарт есть в тексте статьи. RFC 9110 заменил и 2616, и 723*.

9.3.1. GET

Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]). A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.

Все еще не запрещено полностью, можно если сервер сам просит "ебни меня GETом чувак". Вся секция из 9110 про "можно если осторожно", говорит о том что есть стандарт 2616, а есть реализации. Повернуть взад и запретить уже нельзя, разрешить нельзя. Как и раньше нужен клиент поддерживающий GET с message body и сервер с аналогичной поддержкой.

…что неприменимо к публичным HTTP API да и к REST как методологии (реализации клиента и сервера должны быть независимы)

Ну и, в целом, понятно почему. Потому что читается это вот так:

тело сообщения НЕ ДОЛЖНО включаться в в запрос, если спецификация метода НЕ РАЗРЕШАЕТ. Не «запрещает», а именно «не разрешает»

В спецификации метода GET нет РАЗРЕШЕНИЯ на посылку тела (как и, скажем, в описании CONNECT, DELETE и HEAD — нигде не сказано, что тела у этих методов нет; а вот в описании PUT, POST и OPTIONS прямым текстом такое РАЗРЕШЕНИЕ есть) — что как раз трактуется согласно параграфу 4.3 как запрет иметь body. Очевидно, это плохие формулировки, и запретить тело GET-запросам следовало явно (как это почему-то было сделано для метода TRACE). Но имеем что имеем — в последующих RFC формулировку смягчили до SHOULD NOT и описали зоопарк реализаций.

К ReST стоит относиться как к интерфейсу для Key-Value базы данных. URI играют роль ключей. GET это операция чтения значения.

Идея в том, что ответ на GET запрос должен определяться только URI (как значение в ячейке памяти зависит лишь от ее адреса). Если он будет зависеть от body (ну то есть если для чтения из ячейки мы передаём что-то кроме ее адреса), то это противоречит исходному принципу. Но если представить ситуацию, когда значение, передаваемое в body не влияет на результат GET запроса, то архитектуре в принципе без разницы. Поэтому там нет жёсткого запрета.

в этой главе Филдинг методично перечисляет ограничения, с которыми приходится сталкиваться разработчику

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

REST как архитектурный стиль штука довольно абстрактная. Он не связан с HTTP напрямую, вы можете использовать те же принципы и на базе других протоколов (даже для работы с памятью напрямую, проектируя IPC, без дополнительных слоев).

очевидно, что требование code-on-demand противоречит требованию независимости клиента и сервера — клиент должен уметь интерпретировать код с сервера, написанный на вполне конкретном языке.

Интерпретировать утверждения нужно в том же контексте, где они были сформулированы. Code on demand опциональная фича, на случай если вы хотите доставлять логику обработки вместе с данными. Например это JavaScript в web.

Что касается правила на букву S («stateless»), то систем, в которых сервер вообще не хранит никакого контекста клиента в мире вообще практически нет, поскольку почти ничего полезного для клиента в такой системе сделать нельзя.

Stateless, здесь речь идёт о свойствах интерфейса, обеспечивающего коммуникацию, а не приложения. Контрпример это те же сокеты, где клиент и сервер оба должны помнить состояние открытого соединения (из-за чего вы не можете в произвольный момент увеличить производительность обработки просто добавив ещё сетей или машинок).

Как-то странно, что вы начали подробно расписывать составляющие URL, но не указали, что там перед хостом может быть еще и userinfo. Ну и ссылка на RFC 3986, имхо, так же могла бы быть уместной.

но не указали, что там перед хостом может быть еще и userinfo

Указал: «помимо указанных компонентов в стандарте перечислены разнообразные
исторические наслоения (например, передача логинов и паролей в URL или
использование не-UTF кодировки), которые нам в рамках вопросов
дизайна API неинтересны.»

Ну и ссылка на RFC 3986, имхо, так же могла бы быть уместной.

URI как концепция отдельно от URL не очень интересен в рамках дизайна API. Но да, будет не лишней, добавлю. Спасибо.

Указал...

Да, но если уж был перечислен порядок следования и даже отдельно был расписан achor, то странно было не увидеть userinfo.

Возможно, переставлю абзац выше, спасибо.

Почему метод GET считается идемпотентным, если в многопользовательском окружении объект может быть изменен/удален другим пользователем, и следующий вызов GET с тем же url вернет другой результат или 404?

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

А почему так? В архитектуре API предполагается однопользовательская работа?

Sign up to leave a comment.

Articles