2008-08-07 13 views

risposta

16

Un etag è una stringa arbitraria che il server invia al client che il client invierà di nuovo al server la prossima volta che viene richiesto il file.

L'etag deve essere calcolabile sul server in base al file. Un po 'come un checksum, ma potresti non voler controllare ogni file che lo invia.

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) 

Ho creato una stringa nel formato "numero di inode del file/datestamp/dimensione del file". Quindi, se un file viene modificato sul server dopo che è stato distribuito al client, il nuovo etag rigenerato non corrisponderà se il client lo richiede nuovamente.

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

Se mtime è il momento dell'ultima modifica del file, qual è lo scopo della dimensione e dell'inode? – Steve

+0

Nel mio caso, è perché era un percorso calcolato da un programma CGI. Hai ragione che nel caso di un percorso diretto che il mtime sarebbe probabilmente sufficiente. Dato che il costo sarà principalmente in stat(), non vi è alcun costo aggiuntivo per includere l'inode e la dimensione, che potrebbero proteggere dal (abbastanza improbabile, ovviamente) caso in cui un amministratore di rogue possa aggiornare un file e toccarlo di nuovo l'originale mtime. –

+0

@MarkHarrison, perché hai bisogno delle virgolette sull'etag? È una parte obbligatoria della sintassi? – Pacerier

6

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

Per impostazione predefinita, sia Apache e IIS incorporare i dati nel ETag che riduce drasticamente le probabilità del test di validità successo su siti web con più server.

...

Se non stai approfittando del modello di validazione flessibile che forniscono ETags, è meglio per rimuovere solo l'ETag del tutto.

17

Fintanto che cambia ogni volta che cambia la rappresentazione della risorsa, il modo in cui la produci dipende interamente da te.

Si dovrebbe cercare di produrlo in un modo che in aggiunta:

  1. non richiede di ri-calcolare su ogni GET condizionale, e
  2. non cambia se il contenuto delle risorse hasn 't changed

L'utilizzo di hash del contenuto può causare l'errore al # 1 se non si memorizzano gli hash calcolati insieme ai file.

L'utilizzo dei numeri di inode può causare l'errore al # 2 se si riorganizza il filesystem o si fornisce contenuto da più server.

Un meccanismo che può funzionare è utilizzare qualcosa interamente dipendente dal contenuto come un hash SHA-1 o una stringa di versione, calcolata e archiviata una volta ogni volta che cambia il contenuto della risorsa.

0

Raccomanderei di non usarli e andare invece per le intestazioni modificate per ultime.

Askapache ha un utile articolo su questo. (Come fanno praticamente tutto sembra!)

http://www.askapache.com/htaccess/apache-speed-etags.html

+1

link di askapache è rotto – bskinnersf

+0

Hmm, è un peccato, speriamo che tornino presto perché il sito era una miniera di consigli! –

+0

Il collegamento è ora disponibile. –

2

come generare l'ETAG predefinita apache in 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 

Anche quando ero alla ricerca di qualcosa di esattamente come l'ETAG (il browser chiede un file solo se è cambiato sul server), non ha mai funzionato e ho finito di usare un trucco GET (aggiungendo un timestamp come argomento get ai file js).

1

Ive sta usando Adler-32 come un accorciatore di link html. Non sono sicuro che questa sia una buona idea, ma finora non ho notato alcun duplicato. Può funzionare come generatore di etag. E dovrebbe essere più veloce, quindi provare ad usare hash usando uno schema di crittografia come sha, ma non l'ho verificato. Il codice che uso è:

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