首页 文章

HTTP ETag和HTTP重定向

提问于
浏览
3

我有一个Web服务器,它在响应中发出 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
}

它目前没有问题 .

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

我的问题是这个 . 我要求“http://foo.com/bar.html” . 服务器使用 302 FoundLocation 标头将我重定向到“http://foo.com/qux.html ". I then request " http://foo.com/qux.html”并获得 200 OK 以及 ETag 标头 .

使用什么URL关联上一个响应中的 ETag 标头?

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

2 回答

  • 2

    ETag与当前请求的"selected representation"关联 . 所选的302 Found响应表示"usually contains a short hypertext note with a hyperlink to the different URI(s)."因此,如果302响应包含ETag,则ETag与该超文本相关联 .

    但是,如果在对具有重定向响应的资源的请求中包含ETag,则服务器将忽略ETag . 根据Section 5 of RFC 7232(我的重点):

    如果服务器对没有这些条件的相同请求的响应是2xx(成功)或412(前提条件失败)以外的状态代码,则它必须忽略所有收到的前提条件 . 换句话说,重定向和失败优先于条件请求中前提条件的评估 .

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

  • 3

    正如您在第266行的/src/pkg/net/http/client.go中所见,请求 - 响应周期将持续到以下任一或:

    • http.Client 的重定向检查程序( CheckRedirect 字段)返回错误

    • 收到的回复不是重定向(根据shouldRedirectGet

    在循环期间,先前的响应将被丢弃,并且 client.Do 返回的响应的标头是最后一个响应的响应 .

    这意味着您应该在示例中将 ETagqux.html 关联 .

    302 Found本身是否包含ETag Headers ?

    是的,它可以,但由于它是重定向,客户端将遵循它并从目标URL获取一组新的响应头 .

相关问题