HTTP 内容协商和范围 header
HTTP Content Negotiation and the Range header
Range
header 如何与 Content Negotiation 一起工作? 让我解释一下,但首先让我们同意以下几点:HTTP是无状态协议。
当 HTTP 服务器能够发送单个资源的多个表示时,内容协商用于确定发送哪个表示:客户端可能会表明其偏好(即英语和 GIF),然后服务器将遵守或 - - 在它不能的情况下——服务器会通过一些启发式评估来选择发送给客户端的表示形式。
到目前为止一切顺利...但是当您将 Range
加入其中时会发生什么?
想象一下以下场景:
John is in an airport in Paris and his browser sends an HTTP request.
For some reason, his browser doesn't indicates any preferences in content type,
language nor compression.
GET /uri HTTP/1.1
Host: example.com
Since it has very little to go by, the server, through some heuristics, decides
to send the french representation of the URI (the IP is recognized as being from France.)
200 Okay
Accept-Ranges: bytes
Content: text/html
Content-Language: fr
....data...
Mid-transfer, John stops the download to catch his flight. John resumes his download
once he arrives in New York.
GET /uri HTTP/1.1
Host: example.com
Range: 2000-3000
Again, with little information on the client's preference, the server this time decides
to send the english representation of the URI (the IP is recognized as being from New York.)
至此,文件已损坏,因为其中一部分是法语,另一部分是英语。
猜想:
- 客户可能会记住第一个响应中的内容类型和语言,以便
将该信息发送回服务器以用于第二个请求(在
Accept: text/html Accept-Language: fr
下)。
然而,由于 nether RFC2616 nor RFC7233 对此有任何说明(甚至不是建议),我相信 HTTP 客户端
这种行为很少见......但我还没有测试它。
备注:
- 在上面的场景中,我们可以很容易地让客户端发送首选项并让服务器无法遵守......并且仍然回退到其他启发式。问题依旧。
- 再举个例子,这个问题也存在于另一个SO问题中:
TL;DR
GET /uri HTTP/1.1
Host: example.com
Accept: text/html; q=1.0, text/plain; q=0.8, */*; q=0.1
Accept-Language: en; q=1.0, */*; q=0.1
Range: 100-200
在上面,范围适用于请求资源的哪个表示?!
简短回答:不要在没有 If-Match 的情况下使用范围请求:etag 请求 header 字段。
Range
header 如何与 Content Negotiation 一起工作? 让我解释一下,但首先让我们同意以下几点:HTTP是无状态协议。
当 HTTP 服务器能够发送单个资源的多个表示时,内容协商用于确定发送哪个表示:客户端可能会表明其偏好(即英语和 GIF),然后服务器将遵守或 - - 在它不能的情况下——服务器会通过一些启发式评估来选择发送给客户端的表示形式。
到目前为止一切顺利...但是当您将 Range
加入其中时会发生什么?
想象一下以下场景:
John is in an airport in Paris and his browser sends an HTTP request. For some reason, his browser doesn't indicates any preferences in content type, language nor compression.
GET /uri HTTP/1.1 Host: example.com
Since it has very little to go by, the server, through some heuristics, decides to send the french representation of the URI (the IP is recognized as being from France.)
200 Okay Accept-Ranges: bytes Content: text/html Content-Language: fr ....data...
Mid-transfer, John stops the download to catch his flight. John resumes his download once he arrives in New York.
GET /uri HTTP/1.1 Host: example.com Range: 2000-3000
Again, with little information on the client's preference, the server this time decides to send the english representation of the URI (the IP is recognized as being from New York.)
至此,文件已损坏,因为其中一部分是法语,另一部分是英语。
猜想:
- 客户可能会记住第一个响应中的内容类型和语言,以便
将该信息发送回服务器以用于第二个请求(在
Accept: text/html Accept-Language: fr
下)。 然而,由于 nether RFC2616 nor RFC7233 对此有任何说明(甚至不是建议),我相信 HTTP 客户端 这种行为很少见......但我还没有测试它。
备注:
- 在上面的场景中,我们可以很容易地让客户端发送首选项并让服务器无法遵守......并且仍然回退到其他启发式。问题依旧。
- 再举个例子,这个问题也存在于另一个SO问题中:
TL;DR
GET /uri HTTP/1.1
Host: example.com
Accept: text/html; q=1.0, text/plain; q=0.8, */*; q=0.1
Accept-Language: en; q=1.0, */*; q=0.1
Range: 100-200
在上面,范围适用于请求资源的哪个表示?!
简短回答:不要在没有 If-Match 的情况下使用范围请求:etag 请求 header 字段。