HTTP ETag和HTTP重定向

时间:2014-04-11 13:32:49

标签: http go etag

我有一个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 Found重定向我,Location标头重定向到“http://foo.com/qux.html”。然后,我请求“http://foo.com/qux.html”并获得200 OK以及ETag标题。

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

302 Found本身是否包含ETag标题?

2 个答案:

答案 0 :(得分:3)

正如您在第266行的/src/pkg/net/http/client.go中所看到的,请求 - 响应周期将继续,直到或:

  • http.Client的重定向检查器(CheckRedirect字段)返回错误
  • 收到的回复不是重定向(根据shouldRedirectGet

在循环期间,之前的响应将被丢弃,而client.Do返回的响应的标题是最后一个响应的响应。

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

  

302 Found本身是否包含ETag标题?

是的,但可以,但由于它是重定向,客户端将关注它并从目标网址获取一组新的响应标头。

答案 1 :(得分:2)

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

但是,如果在对具有重定向响应的资源的请求中包含ETag,则服务器将忽略ETag。根据{{​​3}}(我的强调):

  

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

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