为什么 Nginx etag 是根据上次修改时间和内容长度创建的?

jun*_*lin 4 etag nginx http-caching

Nginx etag源

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;

r->headers_out.etag = etag;
Run Code Online (Sandbox Code Playgroud)

如果服务器中的文件last-modified-time发生了变化,但文件内容没有更新,那么etag值会一样吗?

为什么不是内容哈希etag生成的值?

Kev*_*nry 5

\n

为什么不是内容哈希生成的etag值?

\n
\n

除非 nginx 已经记录了原因,否则很难说出原因。

\n

我的猜测是他们这样做是因为速度非常快并且只需要恒定的时间。计算哈希可能是一项成本高昂的操作,所需的时间取决于响应的大小。nginx 以简单和速度而闻名,但可能不愿意增加这样的开销。

\n
\n

如果服务器中的文件last-modified-time改变了,但文件内容没有更新,那么etag值会一样吗?

\n
\n

不,它不会相同,因此必须重新提供该文件。结果是比基于哈希的响应慢ETag,但响应是正确的。

\n

该算法更大的问题是内容可能会发生变化,而内容保持ETag不变,在这种情况下,响应将不正确。如果文件更改(以保持相同长度的方式)快于时间的一秒精度,则可能会发生这种情况Last-Modified。(理论上,基于散列的方法具有相同的问题\xe2\x80\x94,即两个不同的文件可能产生相同的散列\xe2\x80\x94,但冲突的可能性很小,因此在实践中不必担心。)

\n

因此,想必 nginx 权衡了这一权衡\xe2\x80\x94a 更快的响应,但有轻微的机会出现错误\xe2\x80\x94,并认为这是值得的。

\n