2008-08-07 58 views

回答

16

etag是服務器發送給客戶端的一個任意字符串,下次請求文件時,客戶端將發送回服務器。

etag應該可以在服務器上根據文件進行計算。有點像校驗和,但你可能不希望校驗和發送出去的每個文件。

server    client 

     <------------- request file foo 

file foo etag: "xyz" --------> 

     <------------- request file foo 
         etag: "xyz" (what the server just sent) 

(the etag is the same, so the server can send a 304) 

我建立了格式爲「file inode number/datestamp/file size」的字符串。因此,如果服務器上的文件在服務器上發送給客戶端後發生了更改,那麼如果客戶端重新請求它,則新重新生成的etag將不匹配。

 
char *mketag(char *s, struct stat *sb) 
{ 
    sprintf(s, "%d/%d/%d", sb->st_ino, sb->st_mtime, sb->st_size); 
    return s; 
} 
+2

如果mtime是文件上次更改的時間,那麼size和inode的用途是什麼? – Steve 2010-02-04 03:20:41

+0

就我而言,這是因爲它是來自CGI程序的計算路徑。你說得對,如果是直接路徑,那麼這個時間可能就足夠了。由於成本主要在stat()中,因此包含inode和大小不需要額外的費用,這可以防止流氓管理員可能更新文件並將其重新接觸到(當然不太可能)的情況原始的mtime。 – 2010-02-04 04:21:52

6

http://developer.yahoo.com/performance/rules.html#etags

默認情況下,Apache和IIS都在顯着減少的有效性測試成功與多個服務器的網站的機率ETag的嵌入數據。

...

如果你不採取靈活的驗證模型的ETag提供的優勢,最好只刪除ETag的乾脆。

17

只要資源表示發生變化,只要它發生變化,您如何生成它完全取決於您。

你應該嘗試製作它的方式,另外:

  1. 不要求您重新計算它在每個有條件的GET和
  2. 如果資源內容不是招不改變不會改變

如果您不存儲計算出的哈希與文件一起使用內容哈希會導致您在#1失敗。

如果您重新排列文件系統或從多個服務器提供內容,則使用inode編號可能會導致在#2時出現故障。

可以工作的一種機制是使用完全依賴於內容的內容(如SHA-1哈希或版本字符串),每當您的資源內容更改時計算並存儲一次。

2

如何生成默認的Apache ETAG在bash

for file in *; do printf "%x-%x-%x\t$file\n" `stat -c%i $file` `stat -c%s $file` $((`stat -c%Y $file`*1000000)) ; done 

甚至當我在尋找的東西完全一樣的eTag(瀏覽器僅當它在服務器上發生變化時纔會請求文件),它從來沒有工作過,並且我使用GET技巧(將時間戳添加爲js文件的get參數)。

1

我一直使用Adler-32作爲html鏈接縮寫。林不知道這是否是一個好主意,但到目前爲止,我沒有注意到任何重複。它可能作爲一個etag生成器。而且它應該更快,然後嘗試使用像sha這樣的加密方案進行散列,但是我沒有驗證過這一點。我使用的代碼是:

shortlink = str(hex(zlib.adler32(link)+(2**32-1)/2))[2:-1]