LINUX.ORG.RU

Можно ли слепо полагаться на Last-Modified?

 , , lua-sec, ,


0

1

Суть, есть велосипедик очередной, проверяет изменения на веб страничках, это я так узнаю про новости, проверяет сейчас в лоб, скачивает страницу и с горем пополам извлекает текст и делается нечто вроде diff от предыдущей сохранённой страницы, совпадающий текст заменяется * звёздочками так я вижу что изменилось на странице, типа вот так

Всё бы ладно, но в большинстве случаев, обновлений на страницах нет. Вот все кнопки что коричневые это значит что на странице ничего не изменилось. Но узнаёт программа про это, только целиком скачав страницу и сравнив с предыдущей копией в лоб. Подумалось что правильнее будет узнавать какой Last-Modified и на основании его уже качать или не качать новые данные со страницы. Вопрос, Last-Modified может врать? Если да, то как часто это делает. Может там неписаные правила какие настройки вебсерверов.

И сразу второй вопрос, нужно ли сначала делать запрос If-Modified-Since для явного указания что я хочу узнать изменилась ли страница с предыдущей даты конкретной или просто можно читать Last-Modified и сравнивать даты чисто на своей стороне, в смысле может ли быть что Last-Modified вернётся новым тогда и только тогда когда был запрос с If-Modified-Since?

Хочется просто пропускать загрузку страниц для проверки, если они реально без обновлений. В правильную ли я сторону думаю?

Я параллельно сам читаю всякое, но думаю спросить лишним не будет =)

Подумалось что правильнее будет узнавать какой Last-Modified и на основании его уже качать или не качать новые данные со страницы. Вопрос, Last-Modified может врать? Если да, то как часто это делает. Может там неписаные правила какие настройки вебсерверов.

Если на странице есть изменения, то Last-Modified изменится (иначе пользователи браузеров увидят версию из локального кэша). Обратное неверно, т.е. если у двух версий разные Last-Modified, это не значит, что у них непустой дифф.

Никаких «правил» настройки помимо RFC нет, и заголовок может выдавать не веб-сервер, а приложение (если это не статика).

И сразу второй вопрос, нужно ли сначала делать запрос ` для явного указания что я хочу узнать изменилась ли страница с предыдущей даты конкретной или просто можно читать Last-Modified и сравнивать даты чисто на своей стороне, в смысле может ли быть что Last-Modified вернётся новым тогда и только тогда когда был запрос с If-Modified-Since?

При запросе с If-Modified-Since если нет изменений, то сервер вернёт 304 с пустым телом ответа. Никакой разницы быть не должно, кроме скачивания лишних данных и лишней нагрузки на сервер.

В правильную ли я сторону думаю?

Если сервер контролируемый, то имеет смысл перейти на ETag, используя хэш от содержимого страницы.

annulen ★★★★★
()

В большинстве нестатических страниц это поле содержит просто текущее время. Или ещё какую нерелевантную ерунду.

А, ну, да, и как выше пишут его часто вообще нет.

Если да, то как часто это делает. Может там неписаные правила какие настройки вебсерверов.

Для статики это дата изменения файла, которую отдаёт веб-сервер. Для не-статики это то, что отдаст скрипт (пхп-питон-итд), если его авторы вообще об этом задумались и правильно понимают смысл этого поля.

просто можно читать Last-Modified и сравнивать даты чисто на своей стороне

Это бессмысленно - если ты уже сделал запрос и получил ответ, то время ты всё равно потратил, а экономить на времени работы диффа это ерунда. Суть именно в том чтобы неизменившиеся страницы даже не начинать скачивать.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 3)

Last-Modified может врать?

Может, конечно, всё может врать.

как часто это делает.

Вряд ли часто. Обычно этот заголовок ставит веб-сервер для статики, исходя из даты изменения соответствующего файла. Для динамики его скрипты редко ставят. Но если ставят, тут уже всё на откуп программисту.

нужно ли сначала делать запрос If-Modified-Since

Про «сначала» не понял. Если тебе прошлый раз вернули Last-Modified, то есть смысл добавить этот заголовок к следующему запросу. Сервер в теории может тебе ответить HTTP 304 Not Modified и немного сохранить трафика.

читать Last-Modified и сравнивать даты чисто на своей стороне

В этом смысла немного. Если тебе ушли заголовки, то и тело уйдёт. Ты тут вряд ли что-то сэкономишь, отказываясь от чтения тела.

может ли быть что Last-Modified вернётся новым тогда и только тогда когда был запрос с If-Modified-Since?

Может быть что угодно, но вряд ли это где-то есть.

Хочется просто пропускать загрузку страниц для проверки, если они реально без обновлений. В правильную ли я сторону думаю?

Я думаю, что ты занимаешься бесполезным делом. В динамических ответах крайне редко кто-то ставит этот заголовок и учитывает If-Modified-Since, поэтому твой код просто не будет срабатывать. Для статики это нужно и полезно, но судя по описанию статика тебе не нужна.

vbr ★★★
()

Это целиком на совести разрабов сайта. Кто-то заморочился, кто-то забил. Для страниц, которые строятся из десятков источников данных, которые независимо обновляются сложность вычисления last-modified может быть сопоставима с сложностью отдачи страницы с нуля

cobold ★★★★★
()

нужно ли сначала делать запрос If-Modified-Since для явного указания что я хочу узнать изменилась ли страница с предыдущей даты конкретной или просто можно читать Last-Modified и сравнивать даты чисто на своей стороне, в смысле может ли быть что Last-Modified вернётся новым тогда и только тогда когда был запрос с If-Modified-Since?

If-Modified-Since нужен не для этого, а чтобы ты одним HTTP запросом все узнал. Ты передаешь в If-Modified-Since время версии, которая у тебя есть в кеше, и потом тебе если страничка изменилась, ее выдают, а если нет, то выдают специальный HTTP код. Но на практике это работает только для статики типа картинок, а динамика всегда будет возвращать всю страницу, разве что у сайта дофига технологичный движок.

goingUp ★★★★★
()
Ответ на: комментарий от cobold

Для страниц, которые строятся из десятков источников данных, которые независимо обновляются сложность вычисления last-modified может быть сопоставима с сложностью отдачи страницы с нуля

Ну ерунда же. Обычный сервер типа nginx это посчитает на лету перед отдачей клиенту и затраты на это будут близки к нулю.

anonymous
()
Ответ на: комментарий от anonymous

Неудобно от анонима писать, так бы соединил все свои комменты в один.

Короче говоря, как я делаю:

  1. Делаю HEAD, смотрю код ответа, если там 304 то заканчиваю.

  2. Если другой (обычно 200), то делаю GET и обрабатываю ответ заново.

anonymous
()
Ответ на: комментарий от anonymous

Не везде есть rss. А если есть туда наваливают всё что надо и не надо. Я просто беру страничку проекта и кидаю себе в базу и всё.

Иногда запускаю программу и гляжу у кого чего нового :)

LINUX-ORG-RU ★★★★★
() автор топика

Короче, немного статистики

 из 579 ссылок 291 не поддерживают дату обновления
 из 579 ссылок 48 пишут текущую дату и время в дате обновления (+48 лишних запросов)
 из 579 ссылок 240 дают корректную информацию, а 339 пишут тутфту

Нууу, такое себе. Ладно. Пойдёт. На пару минут побыстрее стало.

А ещё lua-sec/lua-socket или ltn12 или все вместе тормоза.
Курлом через popen быстрее работает. Пока лень выяснять кто виноват. Ну да и пофиг, потом починим скорости.

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)