33

如果客户端发送 HTTP 请求并指定服务器无法解码的 Content-Encoding 标头,应该返回什么状态码?

例子

客户端将 JSON 数据 POST 到 REST 资源并使用 gzip 编码对实体主体进行编码。但是,服务器只能解码 DEFLATE 编码,因为它未能通过服务器学校的 gzip 类。

应该返回什么 HTTP 响应代码?我会说415 Unsupported Media Type但问题不是实体的 Content-Type ——而是其他支持的实体主体的编码。

哪个更合适:415?400?也许是自定义响应代码?


附录:当然,我已经彻底检查了 rfc2616。如果答案在那里,我可能需要一些新的矫正眼镜,但我不相信它是。


更新:

这与发送客户端可能无法接受的响应无关。问题是客户端正在向服务器发送可能是也可能不是服务器无法理解的编码中的有效媒体类型(根据Content-Encoding客户端与请求消息一起打包的标头)。

这是一个边缘情况,在处理浏览器用户代理时不会遇到,但它可能会出现在接受实体主体以创建/修改资源的 REST API 中。

4

2 回答 2

55

当我读它时,415 Unsupported Media Type听起来最合适。

来自 RFC 2616:

10.4.16 415 不支持的媒体类型

服务器拒绝为请求提供服务,因为请求的实体采用所请求方法的请求资源不支持的格式。

是的,文本部分说的是“媒体类型”而不是“编码”,但实际的描述并没有提到这种区别。

新的热点RFC 7231甚至是明确的:

6.5.13。415 不支持的媒体类型

415(不支持的媒体类型)状态代码表示
源服务器拒绝为请求提供服务,因为有效负载
的格式不受目标资源上此方法的支持。
格式问题可能是由于请求指示的
Content-Type 或 Content-Encoding
,或者是直接检查
数据的结果。

于 2012-07-13T21:18:55.310 回答
11

他们应该把这个问题作为关于谁想成为百万富翁的最后一个问题!

好吧,浏览器发出了服务器无法服务的请求,因为客户端提供的信息采用服务器无法处理的格式。但是,这不是服务器不支持客户端提供的数据的错,而是客户端没有监听服务器的 Acccept-* 标头并以不适当的编码提供数据的错。这将使其成为客户端错误(400 系列错误代码)。

  • 我的第一直觉是 400 Bad Request 在这种情况下是适当的响应。
  • 405 Method Not Allowed 是不对的,因为它指的是 HTTP 动词是不允许的。
  • 406 Not Acceptable 看起来可能有承诺,但它指的是服务器无法向客户端提供满足其发送的 Accept-* 请求标头的数据。这似乎不适合您的情况。
  • 412 Precondition Failed 的定义相当模糊。这可能是合适的,但我不会打赌。
  • 415 Unsupported Media Type 不正确,因为被拒绝的不是数据类型,而是编码格式。

之后,我们进入非标准响应代码的领域。

  • 422 Unprocessable Entity 描述了一个响应,如果请求格式正确但在某种意义上它在语义上不正确,则应返回该响应。这看起来很合适,但它是 HTTP 的 WebDAV 扩展,而不是标准。

鉴于上述情况,我个人会选择 400 Bad Request。如果任何其他 HTTP 专家有更好的候选人,我会听他们的。;)

更新:我之前一直在他们的维基百科页面上引用 HTTP 状态。虽然那里的信息似乎是准确的,但也不够全面。查看W3C的规范提供了更多关于 HTTP 406 的信息,这让我认为 406 可能是正确的代码。

10.4.7 406 不可接受

请求标识的资源只能根据请求中发送的接受头生成具有不可接受的内容特征的响应实体。

除非它是一个 HEAD 请求,否则响应应该包括一个实体,该实体包含一个可用实体特征和位置的列表,用户或用户代理可以从中选择最合适的一个。实体格式由 Content-Type 标头字段中给出的媒体类型指定。根据用户代理的格式和能力,可以自动选择最合适的选项。但是,本规范没有为这种自动选择定义任何标准。

  Note: HTTP/1.1 servers are allowed to return responses which are
  not acceptable according to the accept headers sent in the
  request. In some cases, this may even be preferable to sending a
  406 response. User agents are encouraged to inspect the headers of
  an incoming response to determine if it is acceptable.

如果响应可能不可接受,用户代理应该暂时停止接收更多数据并询问用户以决定进一步的操作。

虽然它明确提到了 Content-Type 标头,但措辞提到了“实体特征”,您可以将其解读为涵盖 GZIP 与 DEFLATE 压缩等内容。

值得注意的一件事是,规范说,只发送数据可能是合适的,连同标头一起告诉客户端它采用什么格式以及它使用什么编码,并将其留给客户端进行整理. 因此,如果客户端发送一个表明它接受 GZIP 压缩的标头,但服务器只能生成一个带有 DEFLATE 的响应,那么将它与标头一起发送说它是 DEFLATE 应该没问题(取决于上下文)。

  • 客户:给我一个 GZIPPED 页面。
  • 服务员:对不起,没办法。我可以给你放气。这是 DEFLATE 打包页面。这对你好吗?
  • 客户:嗯……我并不是真的想要 DEFLATE,但我可以解码它,所以我会接受它。

(或者)

  • 客户:我想我得和我的用户说清楚。坚持,稍等。
于 2012-07-12T21:57:21.173 回答