HTTP:Генерация заголовка ETag
-
08-06-2019 - |
Вопрос
Как мне сгенерировать HTTP-заголовок ETag для файла ресурсов?
Решение
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)
Я создал строку в формате "номер индексного индекса файла / метка даты / размер файла".Таким образом, если файл изменен на сервере после того, как он был отправлен клиенту, вновь созданный etag не будет соответствовать, если клиент повторно запросит его.
char *mketag(char *s, struct stat *sb) { sprintf(s, "%d/%d/%d", sb->st_ino, sb->st_mtime, sb->st_size); return s; }
Другие советы
Поскольку он меняется всякий раз, когда меняется представление ресурса, способ его создания полностью зависит от вас.
Вы должны попытаться создать его таким образом, чтобы дополнительно:
- не требует, чтобы вы повторно вычисляли его при каждом условном получении, и
- не изменяется, если содержимое ресурса не изменилось
Использование хэшей содержимого может привести к сбою на # 1, если вы не сохраните вычисленные хэши вместе с файлами.
Использование номеров индексов может привести к сбою на # 2, если вы перестроите свою файловую систему или будете обслуживать контент с нескольких серверов.
Один из механизмов, который может сработать, - это использовать что-то полностью зависящее от содержимого, такое как хэш SHA-1 или строка версии, вычисляемое и сохраняемое один раз при изменении содержимого вашего ресурса.
От http://developer .yahoo.com/performance/rules.html#etags:
По умолчанию и Apache, и IIS встраивают данные в ETag, что значительно снижает вероятность успешного прохождения теста достоверности на веб-сайтах с несколькими серверами.
...
Если вы не используете преимущества гибкой модели проверки, предоставляемой ETags, лучше просто вообще удалить ETag.
Как сгенерировать etag apache по умолчанию в 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 (добавление метки времени в качестве аргумента get к файлам js).
Я использовал Adler-32 в качестве средства сокращения html-ссылок.Я не уверен, хорошая ли это идея, но пока я не заметил никаких дубликатов.Он может работать как генератор etag.И это должно быть быстрее, чем пытаться хэшировать, используя схему шифрования, подобную sha, но я не проверял это.Код, который я использую, это:
shortlink = str(hex(zlib.adler32(link)+(2**32-1)/2))[2:-1]
Я бы рекомендовал не использовать их и вместо этого использовать заголовки с последними изменениями.
У Askapache есть полезная статья на эту тему.(поскольку они делают практически все, что кажется!)