1. 程式人生 > >面試官:如果 http 響應頭中 ETag 值改變了,是否意味著檔案內容一定已經更改

面試官:如果 http 響應頭中 ETag 值改變了,是否意味著檔案內容一定已經更改

本篇文章由我的 一日一題 中的四個 Issue 組合而成

  • 【Q111】http 響應頭中的 ETag 值是如何生成的
  • 【Q112】如果 http 響應頭中 ETag 值改變了,是否意味著檔案內容一定已經更改
  • 【Q115】檔案系統中 mtime 和 ctime 指什麼,都有什麼不同
  • 【Q116】http 服務中靜態檔案的 Last-Modified 是根據什麼生成的

不一定,由伺服器中 ETag 的生成演算法決定。詳見 #112

比如 nginx 中的 etaglast_modifiedcontent_length 組成,而 last_modified 又由 mtime 組成

當編輯檔案卻未更改檔案內容時,mtime 也會改變,此時 etag 改變,但是檔案內容沒有更改。

http 服務中靜態檔案的 Last-Modified 根據什麼生成

一般會選檔案的 mtime,表示檔案內容的修改時間

nginx 也是這樣處理的,原始碼見: ngx_http_static_module.c

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = of.size;
    r->headers_out.last_modified_time = of.mtime;

那為什麼使用 mtime 而非 ctime

檔案系統中 mtime 和 ctime 指什麼,都有什麼不同

linux 中,

  • mtimemodified time 指檔案內容改變的時間戳
  • ctimechange time 指檔案屬性改變的時間戳,屬性包括 mtime。而在 windows 上,它表示的是 creation time

所以 ctime 會比 mtime 要大一些,使用 stat 檢視檔案屬性如下

$ stat hello.txt
  File: ‘hello.txt’
  Size: 30              Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 917526      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-12-10 16:15:55.253325208 +0800
Modify: 2019-12-10 16:15:52.740653330 +0800
Change: 2019-12-10 16:15:52.742653069 +0800
 Birth: -

而 http 服務選擇 Last_Modified 時一般會選擇 mtime