2008-08-07 77 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]