HTTP ETag 和 HTTP 重定向

标签 http go etag

我有一个网络服务器,它在响应中发出 ETag header ,并检查来自客户端的 If-None-Match header (如果存在)。在这种情况下,客户端不是 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
}

目前一切正常。

我仅为 GET 请求存储和发送 ETag。虽然为其他请求发送它们是有效的,但它不在我当前的用例中,所以我不会打扰它。通过将 url.URL 对象映射到字符串来存储 ETag。

我的问题是这样的。我请求“http://foo.com/bar.html”。服务器使用 302 FoundLocation header 将我重定向到“http://foo.com/qux.html”。然后我请求“http://foo.com/qux.html”并获得 200 OK 以及 ETag header 。

我将上次响应的 ETag header 与哪个 URL 相关联?

302 Found 本身可以包含一个 ETag header 吗?

最佳答案

ETag与当前请求的“选定表示”相关联。 302 Found 的选定表示响应“通常包含一个简短的超文本注释,带有指向不同 URI 的超链接。”因此,如果 302 响应包含 ETag,则 ETag 与该超文本相关联。

但是,如果您在对以重定向响应的资源的请求中包含 If-None-Match(或其他前提条件),服务器将忽略该前提条件。根据Section 5 of RFC 7232 (我的重点):

A server MUST ignore all received preconditions if its response to the same request without those conditions would have been a status code other than a 2xx (Successful) or 412 (Precondition Failed). In other words, redirects and failures take precedence over the evaluation of preconditions in conditional requests.

因此,虽然 302 响应可以包含 ETag,但它没有用,因为服务器可能不会在对该资源的进一步请求中使用它。

关于HTTP ETag 和 HTTP 重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23014106/

相关文章:

php - 如何在 HTTP 服务中进行身份验证?

.net - 在 IIS 中修改 Access-Control-Allow-Origin header

go - 在 Go 中发出 SOAP 请求

azure - 是否可以使用 IF-Match(而不是 ETAG)有条件地更新属性?

java - 特定 Wicket 组件的 URL

.net - 在 HttpClient 上设置代理时出现问题

go - 使用 neo4j go 驱动程序编译 neo4j 代码的问题

go - Kubernetes 围棋 API

ruby-on-rails - Rails - etags 与页面缓存(文件缓存)

azure - 是否可以使用 Azure 表存储进行条件插入