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

关于 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;

总结:nginxetag 由响应头的 Last-ModifiedContent-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-ModifiedContent-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

既然在 nginxETagLast-ModifiedContent-Length 组成,那它便算是一个加强版的 Last-Modified 了,那加强在什么地方呢?

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

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

原文地址:https://www.cnblogs.com/xianwang/p/12019830.html

时间: 2024-09-29 23:46:06

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

Java中生成符合http响应头中的Date格式的字符串

在http header中,Date头域表示消息发送的时间,时间的描述格式由rfc822(电子邮件的标准格式)定义.例如,Date: Sat, 05 Jul 2014 12:53:36 GMT.具体格式说明如下: 标准格式:DAY, DD MMM YYYY HH:MM:SS GMT,其中 DAY: 由三个英文字母指代的星期(Sun, Mon, Tue, Wed, Thu, Fri, Sat). DD: 日(such as 01 for the first day of the month). M

提高安全性而在HTTP响应头中可以使用的各种响应头字段

本文介绍在Web服务器做出响应时,为了提高安全性而在HTTP响应头中可以使用的各种响应头字段.由于部分浏览器中有可能对某些字段或选项不提供支持,所以在使用这些字段时请先确认客户端环境. X-Frame-Options 该响应头中用于控制是否在浏览器中显示frame或iframe中指定的页面,主要用来防止Clickjacking(点击劫持)攻击. X-Frame-Options: SAMEORIGIN DENY 禁止显示frame内的页面(即使是同一网站内的页面) SAMEORIGIN 允许在fr

【协议分析】HTTP响应头中的2种编码方式介绍

HTTP 1.1中有两个实体头(Entity-Header)直接与编码相关,分别为Content-Encoding和Transfer-Encoding.    先说Content-Encoding, 该头表示实体已经采用了的编码方式.Content-Encoding是请求URL对应实体(Entity)本身的一部分.比如请求URL为 http://host/image.png.gz时,可能会得到的Content-Encoding为gzip.Content-Encoding的值是不区分大小写的,目前

http响应头中的X-Frame-Options防止被frame

X-Frame-Options 响应头有3个值: DENY:表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许. SAMEORIGIN:表示该页面可以在相同域名页面的 frame 中展示. ALLOW-FROM uri:表示该页面可以在指定来源的 frame 中展示. Nginx配置:把下列这行添加到Nginx.conf的"http"或"server"或"location"中 add_header X-Frame-Opt

【ASP.NET Core】如何隐藏响应头中的 “Kestrel”

全宇宙人民都知道,ASP.NET Core 应用是不依赖服务器组件的,因此它可以独立运行,一般是使用支持跨平台的 Kestrel 服务器(当然,在 Windows 上还可以考虑用 HttpSys,但要以管理员身份运行). 尽管 SDK 文档中推荐我们用服务器组件来“反向”代理,但独立运行也是允许的.当 Web 应用独立运行的时候,客户端发出请求后,在响应的 HTTP 消息中,会附上一个 Server 头,其值就是 Kestrel.如下面的高清无码无水印截图所示. 看到了吧,Server = Ke

【HTTP协议】响应头中的Content-Length和Transfer-Encoding

来源: http://blog.csdn.net/superhosts/article/details/8737434 http://bbs.csdn.net/topics/390384017 对于http的请求返回结果要进行内容的长度校验主要有两种方式: 1.客户端在http头(head)加Connection:keep-alive时,服务器的response是Transfer-Encoding:chunked的形式,通知页面数据是否接收完毕,例如长连接或者程序运行中可以动态的输出内容,例如一

HTTP协议---HTTP请求中的常用请求字段和HTTP的响应状态码及响应头

http://blog.csdn.net/qxs965266509/article/details/8082810 用于HTTP请求中的常用请求头字段 Accept:用于高速服务器,客户机支持的数据类型 Accept-Charset:用于告诉服务器,客户机采用的编码格式 Accept-Encoding:用于告诉服务器,客户机支持的数据压缩格式 Accept-Language:客户机的语言环境 Host:客户机通过这个头高速服务器,想访问的主机名 If-Modified-Since:客户机通过这个

Http消息头中常用的请求头和响应头

作为Web开发对常用http的请求头和响应头熟悉了解一下还是很有必要的.比如请求头中Content-type指定了请求的内容,若类型是application/x-www-form-urlencoded,就可以调用reqeust的获取参数方法取到内容,若是其它都需要调用获取流的方法获取.又比如响应头X-Frame-Options 的设置直接决定了你的页面是否能被其它非同源的ifream嵌入,而这个设置可以是在html页面中,也可以是框架或代码的响应头设置中,也可以是在http服务器(nginx或t

如何在HTTP头中隐藏PHP版本号

PHP 配置默认允许服务器在 HTTP 响应头 X-Powered-By 中显示安装在服务器上的 PHP 版本.出于服务器安全原因(虽然不是主要的要担心的威胁),建议你禁用或隐藏此信息,避免那些针对你的服务器的攻击者知道你是否运行了 PHP.在本文中,我们将解释如何隐藏或关闭服务器 HTTP 响应头中的 PHP 版本号. PHP 配置默认允许服务器在 HTTP 响应头 X-Powered-By 中显示安装在服务器上的 PHP 版本. 出于服务器安全原因(虽然不是主要的要担心的威胁),建议你禁用或