您的位置:首页 > 理论基础 > 计算机网络

你知道 http 响应头中的 ETag 是如何生成的吗

2019-12-10 23:18 3447 查看

关于

etag
的生成需要满足几个条件

  1. 当文件不会更改时,
    etag
    值保持不变。所以不能单纯使用
    inode
  2. 便于计算,不会特别耗 CPU。这样子
    hash
    不是特别合适
  3. 便于横向扩展,多个
    node
    上生成的
    etag
    值一致。这样子
    inode
    就排除了

关于服务器中

etag
如何生成可以参考 HTTP: Generating ETag Header

那么在

nginx
中的
etag
是如何生成的?

nginx 中 ETag 的生成

我在网上找到一些资料与源代码了解到了

etag
的计算方法。由
python
伪代码表示计算方法如下

etag = '{:x}-{:x}'.format(header.last_modified, header.content_lenth)

源码: ngx_http_core_modules.c

etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
r->headers_out.last_modified_time,
r->headers_out.content_length_n)
- etag->value.data;

总结:

nginx
etag
由响应头的
Last-Modified
Content-Length
表示为十六进制组合而成。

随手在我的k8s集群里找个

nginx
服务测试一下

$ curl --head 10.97.109.49
HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Tue, 10 Dec 2019 06:45:24 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Apr 2019 10:18:21 GMT
Connection: keep-alive
ETag: "5cbee66d-264"
Accept-Ranges: bytes

etag
计算
Last-Modified
Content-Length
,使用
js
计算如下,结果相符

> new Date(parseInt('5cbee66d', 16) * 1000).toJSON()
"2019-04-23T10:18:21.000Z"
> parseInt('264', 16)
612

Last-Modified,ETag 与协商缓存

我们知道协商缓存有两种方式

  • Last-Modified
    /
    if-Modified-Since
  • ETag
    /
    If-None-Match

既然在

nginx
ETag
Last-Modified
Content-Length
组成,那它便算是一个加强版的
Last-Modified
了,那加强在什么地方呢?

**

Last-Modified
是由一个
unix timestamp
表示,则意味着它只能作用于秒级的改变**

那下一个问题:如果 http 响应头中 ETag 值改变了,是否意味着文件内容一定已经更改

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: