33

一些 HTTP 方法,例如POST,要求在 headers 和 double 之后发送正文CRLF

其他的,例如GET,没有正文,对他们来说,双CRLF标是请求的结束。

但是其他人呢:PUT, DELETE, ... 如何知道哪个需要身体?

通用 HTTP 客户端应该如何响应未知的 HTTP 方法?拒绝它?默认需要正文,还是默认不需要正文?

指向相关规范的指针将不胜感激。


编辑:我会详细说明我的问题,正如评论中所问的那样。

我正在设计一个通用的 HTTP客户端,程序员可以使用它向任何服务器发送任意 HTTP 请求。

客户端可以这样使用(伪代码):

HttpClient.request(method, url [, data]);

数据是可选的,可以是原始数据(字符串),也可以是键/值对的关联数组。

如果它是一个数组,该库将对数据进行 url 编码,然后将数据附加到GET请求的 URL 中,或者将其发送到请求的消息正文中POST

因此,鉴于开发人员选择的 HTTP 方法,我试图确定此 HttpClient 是否必须/应该/不得/不应在请求中包含消息正文。

4

5 回答 5

17

编辑:编译列表:

  • 实体主体仅在存在消息主体时才存在(第 7.2 节)
  • 消息体的存在通过包含一个Content-LengthorTransfer-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)是你想要的。根据 RFC:

对于PUT

PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。如果创建了新资源,源服务器必须通过 201 (Created) 响应通知用户代理。如果修改了现有资源,则应发送 200(OK)或 204(No Content)响应代码以指示请求成功完成。如果无法使用 Request-URI 创建或修改资源,应给出反映问题性质的适当错误响应。实体的接收者不得忽略任何它不理解或不实现的 Content-*(例如 Content-Range)标头,并且在这种情况下必须返回 501(未实现)响应。

对于DELETE

DELETE 方法请求源服务器删除由 Request-URI 标识的资源。此方法可能会被源服务器上的人工干预(或其他方式)覆盖。即使从源服务器返回的状态码表明操作已经成功完成,客户端也不能保证操作已经执行。但是,服务器不应指示成功,除非在给出响应时它打算删除资源或将其移动到无法访问的位置。

如果响应包含描述状态的实体,则成功的响应应该是 200(OK),如果操作尚未制定,则为 202(已接受),如果操作已经制定但响应不包括,则应为 204(无内容)一个实体。

如果请求通过缓存并且 Request-URI 标识了一个或多个当前缓存的实体,那么这些条目应该被视为陈旧的。对此方法的响应不可缓存。

于 2013-05-02T13:27:57.170 回答
3

从您的评论中,我了解到您正在编写一个 HTTP 客户端库(为什么,还不够吗?)并且您希望允许使用通用request(method, url[, data])方法。您想知道什么methoddata必需的或禁止的。

假设你的图书馆的用户知道他们在做什么。如果我想发送带有 GET 请求的正文,我可以,因为规范并没有禁止这样做。那么为什么要你的图书馆呢?

此外,HTTP 规范在此开放;HTTP 的扩展(如 WebDAV)可以指定允许或不允许甚至需要消息正文的新方法(动词)。

我认为目前的努力可以更好地用于更重要的部分。

于 2013-05-02T15:25:37.183 回答
3

我要回答这个问题:

  1. 从请求机构的角度来看,而不是响应机构,因为这是被问到的,也是最感兴趣的。
  2. 至于何时需要身体,何时禁止

不需要包含正文的请求,尽管没有正文可能被解释为空正文或零长度之一。

RFC2616 4.3 规定:

4.3 消息正文 消息中何时允许消息正文的规则因请求和响应而异。

...

如果请求方法的规范(第 5.1.1 节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。

浏览 5.1.1 中的方法(不包括任何扩展方法),您会发现:

9.8 跟踪

...

TRACE 请求不得包含实体。

所以从技术上讲,任何其他请求方法:

OPTIONS
GET
HEAD
POST
PUT
DELETE
CONNECT

...可能包括一个身体。回到 4.3:

如果请求方法不包括为实体主体定义的语义,则在处理请求时应该忽略消息主体。

因此,在响应特定方法或资源的意外实体主体时,可以安全地忽略它并做出响应,包括响应代码,就好像没有发送主体一样。

参考:RFC2616 超文本传输​​协议 -- HTTP/1.1

编辑: RFC2616 已经过时了,请参阅RFC7230了解最新规范。

于 2018-06-30T07:38:25.947 回答
0

对于任意方法或您不想在服务器端支持的有效方法,HTTP Status Code 405应将其发送回调用方。

根据http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

405 Method Not Allowed使用资源不支持的请求方法向资源发出请求;[2] 例如,在需要通过 POST 呈现数据的表单上使用 GET,或在只读资源上使用 PUT .

于 2013-05-02T13:36:01.530 回答
0

您可能想阅读有关消息正文长度的当前 HTTP 规范草案部分:http: //greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-22.html#message.body.length

于 2013-05-02T15:17:47.340 回答