我有一个网络服务器,它发出ETag响应的If-None-Match标头并检查来自客户端的标头(如果存在)。在这种情况下,客户端不是 Web 浏览器,而是 go 内置net/http http.Client类型的扩展。
这是我的代码
package util
import "net/http"
import "net/url"
type HttpClient struct {
http.Client
etags map[url.URL]string
}
func (hc *HttpClient) Do(req *http.Request) (*http.Response, error) {
const ETAG_SERVER_HEADER = "ETag"
const ETAG_CLIENT_HEADER = "If-None-Match"
//Do not attempt to use ETags on non-GET requests
if req.Method != "GET" {
return hc.Client.Do(req)
}
//Check for an existing etag
etag, ok := hc.etags[*req.URL]
if ok { //If an ETag is present, send it along
if req.Header == nil {
req.Header = http.Header{}
}
req.Header.Add(ETAG_CLIENT_HEADER, etag)
}
//Do the response
response, err := hc.Client.Do(req)
//If the response is ok
if err == nil {
if hc.etags == nil {
hc.etags = make(map[url.URL]string)
}
//Check for an ETAG from the server, store it if present
etag = response.Header.Get(ETAG_SERVER_HEADER)
if len(etag) != 0 {
hc.etags[*req.URL] = etag
}
}
return response, err
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,它可以正常工作。
我只是存储和发送GET请求的 ETag 。虽然将它们发送给其他请求是有效的,但它目前不在我的用例中,所以我不打扰它。通过将url.URL对象映射到字符串来存储 ETag 。
我的问题是这个。我请求“ http://foo.com/bar.html ”。服务器将我使用302 Found和Location标题重定向到“ http://foo.com/qux.html ”。然后我请求“ http://foo.com/qux.html ”并得到200 OK一个ETag标题。
我ETag将上次响应的标头与哪个 URL 相关联?
可以在302 Found本身包括ETag头?
一个ETag的与当前请求的“选择的表示”相关联。302 Found响应的选定表示“通常包含一个简短的超文本注释,其中包含指向不同 URI 的超链接。” 因此,如果 302 响应包含 ETag,则 ETag 与该超文本相关联。
但是,如果您在对以重定向响应的资源的请求中包含 If-None-Match(或其他前提条件),则服务器将忽略该前提条件。根据RFC 7232 的第 5 节(我的重点):
如果服务器对没有这些条件的相同请求的响应将是 2xx(成功)或 412(前提条件失败)以外的状态代码,则它必须忽略所有接收到的前提条件。换句话说,重定向和失败优先于条件请求中的先决条件的评估。
因此,虽然 302 响应可以包含 ETag,但它没有用,因为服务器可能不会在对该资源的进一步请求中使用它。
| 归档时间: |
|
| 查看次数: |
3839 次 |
| 最近记录: |