Domanda

Come posso generare un'intestazione HTTP ETag per un file di risorse?

È stato utile?

Soluzione

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

L'etag dovrebbe essere calcolabile sul server in base al file.Una specie di checksum, ma potresti non voler eseguire il checksum di 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 inode file/datastamp/dimensione file".Pertanto, se un file viene modificato sul server dopo che è stato servito al client, l'etag appena 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;
}

Altri suggerimenti

Finché cambia ogni volta che cambia la rappresentazione delle risorse, il modo in cui produrlo dipende completamente da te.

Dovresti provare a produrlo in un modo che inoltre:

  1. non richiede di ricalcolarlo su ogni GET condizionale e
  2. non cambia se il contenuto della risorsa non è cambiato

L'uso degli hash di contenuto può farti fallire al punto 1 se non memorizzi gli hash calcolati insieme ai file.

L'uso dei numeri di inode può farti fallire al punto 2 se riorganizzi il tuo filesystem o servi contenuto da più server.

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

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

Per impostazione predefinita, sia Apache che IIS incorporano dati nell'ETag, riducendo drasticamente le probabilità di successo del test di validità su siti Web con più server.

...

Se non stai sfruttando il modello di convalida flessibile fornito dagli ETag, è meglio rimuovere del tutto l'ETag.

Come generare l'etag Apache predefinito 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 stavo cercando qualcosa esattamente come l'etag (il browser richiede un file solo se è cambiato sul server), non ha mai funzionato e ho finito per usare un trucco GET (aggiungendo un timestamp come argomento get ai file js ).

Sto usando Adler-32 come abbreviatore di link HTML.Non sono sicuro che sia una buona idea, ma finora non ho notato alcun duplicato.Potrebbe funzionare come generatore di etag.E dovrebbe essere più veloce rispetto al tentativo di eseguire l'hashing utilizzando uno schema di crittografia come sha, ma non l'ho verificato.Il codice che utilizzo è:

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

Consiglierei di non utilizzarli e di utilizzare invece le intestazioni modificate per ultime.

Askapache ha un articolo utile su questo.(dato che fanno praticamente tutto ciò che sembra!)

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top