Какие методы HTTP требуют тела?
Некоторые HTTP-методы, такие как POST
, требуют отправки тела после заголовков и двойного CRLF
.
Другие, такие как GET
, не имеют тела, а для них двойной CRLF
обозначает конец запроса.
Но как насчет других: PUT
, DELETE
,... как узнать, какой из них требуется тело?
Как общий HTTP-клиент должен реагировать на неизвестный HTTP-метод? Отклонить его? Требуется тело по умолчанию или не требуется тело по умолчанию?
Будет оценен указатель на соответствующую спецификацию.
Изменить. Я подробно расскажу о своем вопросе, как это было задано в комментариях.
Я разрабатываю общий HTTP клиент, который программист может использовать для отправки произвольных HTTP-запросов на любой сервер.
Клиент может использоваться как этот (псевдокод):
HttpClient.request(method, url [, data]);
Данные являются необязательными и могут быть необработанными данными (строкой) или ассоциативным массивом пар ключ/значение.
Библиотека будет кодировать url-данные, если это массив, либо добавить данные в URL-адрес для запроса GET
, либо отправить его в тело сообщения для запроса POST
.
Поэтому я пытаюсь определить, должен ли этот HttpClient/должен/не должен/не должен/не включать тело сообщения в запрос, учитывая метод HTTP, выбранный разработчиком.
Ответы
Ответ 1
РЕДАКТИРОВАТЬ: составленный список:
- тело объекта присутствует только в том случае, если тело сообщения присутствует (раздел 7.2)
- присутствие тела сообщения сигнализируется включением
Content-Length
или Transfer-Encoding
(раздел 4.3) - тело сообщения не должно быть включено, если спецификация метода запроса не позволяет отправить тело объекта (раздел 4.3)
- Тело сущности явно запрещено только в запросах TRACE, все остальные типы запросов не ограничены (в частности, разделы 9 и 9.8)
Для ответов это было определено:
- Включено ли тело сообщения, зависит как от метода запроса, так и от статуса ответа (раздел 4.3).
- Тело сообщения явно запрещено в ответах на запросы HEAD (в частности, разделы 9 и 9.4)
- тело сообщения явно запрещено в ответах 1xx (информационное), 204 (без содержимого) и 304 (не изменено) (раздел 4.3)
- все остальные ответы включают тело сообщения, хотя оно может иметь нулевую длину (раздел 4.3)
Это (RFC 7231) или Эта версия (от IETF & More In-Depth) - это то, что вы хотите. По данным РФЦ:
Для PUT
:
Метод PUT запрашивает, чтобы вложенный объект был сохранен под предоставленным Request-URI. Если Request-URI ссылается на уже существующий ресурс, вложенный объект СЛЕДУЕТ рассматривать как модифицированную версию, находящуюся на исходном сервере. Если Request-URI не указывает на существующий ресурс, и этот URI может быть определен как новый ресурс запрашивающим пользовательским агентом, сервер происхождения может создать ресурс с этим URI. Если новый ресурс создан, сервер происхождения ДОЛЖЕН проинформировать пользовательский агент через ответ 201 (Создано). Если существующий ресурс изменен, то должны быть отправлены коды ответа 200 (ОК) или 204 (Нет содержимого), чтобы указать успешное завершение запроса. Если ресурс не может быть создан или изменен с помощью Request-URI, СЛЕДУЕТ дать соответствующий ответ об ошибке, отражающий природу проблемы. Получатель объекта НЕ ДОЛЖЕН игнорировать заголовки Content- * (например, диапазон Content-), которые он не понимает или не реализует, и ДОЛЖЕН возвращать ответ 501 (не реализовано) в таких случаях.
И для DELETE
:
Метод DELETE запрашивает, чтобы исходный сервер удалил ресурс, указанный в Request-URI. Этот метод МОЖЕТ быть отменен вмешательством человека (или другими средствами) на исходном сервере. Клиент не может быть гарантирован, что операция была выполнена, даже если код состояния, возвращенный с исходного сервера, указывает, что действие было успешно выполнено. Однако серверу НЕ СЛЕДУЕТ указывать успех, если только во время ответа он не намерен удалить ресурс или переместить его в недоступное место.
Успешный ответ ДОЛЖЕН быть 200 (ОК), если ответ включает в себя объект, описывающий статус, 202 (Принят), если действие еще не было выполнено, или 204 (Нет содержимого), если действие было выполнено, но ответ не включает сущность.
Если запрос проходит через кеш, а Request-URI идентифицирует один или несколько кешируемых в данный момент объектов, эти записи ДОЛЖНЫ рассматриваться как устаревшие. Ответы на этот метод не кэшируются.
Ответ 2
Из ваших комментариев я понимаю, что вы пишете клиентскую библиотеку HTTP (почему, их недостаточно?), и вы хотите разрешить общий метод request(method, url[, data])
. Вы хотите знать, для чего method
data
является либо обязательным, либо запрещенным.
Просто предположите, что пользователь вашей библиотеки знает, что они делают. Если я хочу отправить тело с запросом GET, я могу, потому что спецификация не запрещает это. Так почему же ваша библиотека?
Кроме того, в этом случае раскрывается спецификация HTTP; расширение HTTP (например, WebDAV) может указывать новые методы (глаголы), которые делают или не разрешают или даже не требуют тела сообщения.
Я думаю, что нынешние усилия могут быть лучше потрачены на более важные части.
Ответ 3
Я собираюсь ответить на это:
- С точки зрения органов запроса, а не органов ответа, так как это то, о чем спрашивают, и представляет наибольший интерес.
- С точки зрения того, когда тело требуется, а когда это запрещено.
Запрос на включение тела не требуется, хотя отсутствие тела может быть интерпретировано как пустое тело или тело нулевой длины.
RFC2616 4.3 заявляет:
4.3. Тело сообщения Правила для того, когда тело сообщения допускается в сообщении, различаются для запросов и ответов.
...
Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросах.
Проходя через методы в 5.1.1 (исключая любые методы расширения), вы найдете:
9.8 TRACE
...
Запрос TRACE НЕ ДОЛЖЕН включать объект.
Технически, любой из других методов запроса:
OPTIONS
GET
HEAD
POST
PUT
DELETE
CONNECT
... может включать в себя тело. Вернуться к 4.3:
если метод запроса не включает определенную семантику для тела объекта, то тело сообщения ДОЛЖНО игнорироваться при обработке запроса.
Таким образом, в ответ на неожиданное тело объекта для определенного метода или ресурса можно с уверенностью проигнорировать его и ответить, включая код ответа, как если бы тело не было отправлено.
Ссылка: RFC2616 Протокол передачи гипертекста - HTTP/1.1
Изменить: RFC2616 хорошо и действительно устарел, обратитесь к RFC7230 для последней спецификации.
Ответ 4
Для произвольных методов или допустимого метода, который вы не хотите поддерживать на стороне сервера HTTP Status Code 405
, следует отправлять обратно вызывающему абоненту.
По http://en.wikipedia.org/wiki/List_of_HTTP_status_codes:
405 Метод не разрешен. Был запрошен ресурс с использованием метод запроса, не поддерживаемый этим ресурсом; [2], например, используя GET в форме, которая требует, чтобы данные представлялись через POST, или используя PUT на ресурсе, доступном только для чтения.
Ответ 5
Возможно, вам захочется прочитать текущий проект спецификации HTTP-запроса о длине тела сообщения: http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-22.html#message.body.length