2008-08-07 23 views

Respuesta

16

Una etag es una cadena arbitraria que el servidor envía al cliente que el cliente enviará de vuelta al servidor la próxima vez que se solicite el archivo.

El etag debe ser computable en el servidor según el archivo. Más o menos como una suma de comprobación, pero es posible que no desee verificar todos los archivos que lo envían.

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) 

he construido una cadena en el formato de "número de archivo inode/marca de fecha/tamaño de archivo". Por lo tanto, si se cambia un archivo en el servidor una vez que se ha enviado al cliente, el etag recién regenerado no coincidirá si el cliente lo vuelve a solicitar.

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

Si mtime es la hora en que se modificó por última vez el archivo, entonces ¿para qué sirve el tamaño y el inodo? – Steve

+0

En mi caso, es porque era una ruta computada de un programa CGI. Tienes razón en que, en el caso de una ruta directa, el mtime probablemente sea suficiente. Dado que el costo va a ser principalmente en stat(), no hay ningún cargo adicional por incluir el inodo y el tamaño, que podría proteger del (bastante improbable, por supuesto) caso en que un administrador deshonesto pueda actualizar un archivo y volver a tocarlo el mtime original. –

+0

@MarkHarrison, ¿por qué necesitas las comillas dobles para etag? ¿Es una parte obligatoria de la sintaxis? – Pacerier

6

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

Por defecto, Apache y IIS incrustar datos en la ETag que reduce drásticamente las posibilidades de que la prueba de validez tener éxito en los sitios web con múltiples servidores.

...

Si usted no está tomando ventaja del modelo de validación flexible que proporcionan ETags, es mejor eliminar sólo la ETag por completo.

17

Siempre y cuando cambie cada vez que cambie la representación de los recursos, la forma de producirlos depende completamente de usted.

Usted debe tratar de producirlo de una manera que adicionalmente:

  1. no le requerirá para volver a calcular en cada GET condicional, y
  2. no cambia si el contenido del recurso hasn 's cambiado

El uso de hash de contenido puede causar que falle en el n. ° 1 si no almacena los valores hash calculados junto con los archivos.

El uso de números de inodo puede hacer que falle en el n. ° 2 si reorganiza su sistema de archivos o si sirve contenido de varios servidores.

Un mecanismo que puede funcionar es usar algo totalmente dependiente del contenido, como un hash SHA-1 o una cadena de versión, calculada y almacenada una vez cada vez que cambie el contenido de su recurso.

0

Yo recomendaría no utilizarlos y buscar los encabezados modificados en su lugar.

Askapache tiene un artículo útil sobre esto. (Como lo hacen casi todo lo que parece!)

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

+1

enlace askapache está roto – bskinnersf

+0

Hmm, eso es una lástima, espero que vuelvan pronto ya que el sitio fue una mina de oro de asesoramiento! –

+0

El enlace es una copia de seguridad ahora. –

2

cómo generar el etag Apache por defecto en 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 

Incluso cuando yo estaba buscando algo exactamente igual que el etag (el navegador pregunta por un archivo solo si ha cambiado en el servidor), nunca funcionó y terminé usando un truco GET (agregando una marca de tiempo como argumento get a los archivos js).

1

He estado utilizando Adler-32 como un acortador de enlaces html. No estoy seguro si esta es una buena idea, pero hasta ahora, no he notado ningún duplicado. Puede funcionar como generador de etag. Y debería ser más rápido que intentar usar hash usando un esquema de encriptación como sha, pero no he verificado esto. El código que uso es:

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