Если пользователь отменил механизмы кэширования таким образом, что неправильно уменьшил эффективность кэшей, агент пользователя должен непрерывно индицировать (например, изображением горящей купюры) то, что пользователь неосторожно потребляет ресурсы или страдает от чрезмерного времени ожидания.
13.1.5 Исключения из правил и предупреждений.
В некоторых случаях, оператор кэша может сконфигурировать его таким образом, чтобы он возвращал просроченные ответы, даже если они не запрашиваются клиентами. Это решение не должно быть сделано с легкостью, но может быть необходимо по причинам доступности или эффективности, особенно, когда кэш имеет прохое соединение с первоначальным сервером. Всякий раз, когда кэш возвращает просроченный ответ, он должен пометить его (используя заголовок Warning). Это позволяет программному обеспечению клиента предупреждать пользователя, что возможно имеется потенциальная проблема.
Это также позволяет агенту пользователя предпринимать шаги для получения непосредственного (first-hand) или свежего ответа. По этой причине, кэшу не следует возвращать просроченный ответ, если клиент явно запрашивает непосредственный или свежий, за исключением случаев, когда это невозможно выполнить по техническим или стратегическим причинам.
13.1.6 Контролируемое клиентом поведение.
В то время как первоначальный сервер (и меньшей степени промежуточные кэши с их вкладом в возраст ответа) является первичным источником информации об устаревании, в некоторых случаях клиенту может быть необходимо управлять решением кэша о том, возвращать ли кэшированный ответ, не проверяя его достоверность. Клиенты делают это используя несколько директив заголовка управления кэшем (Cache-Control).
Запрос клиента может определять максимальный возраст неутвержденного ответа, который он желает получить; указывая ноль он вынуждает кэш(и) перепроверить достоверность всех ответов. Клиент может также определить минимальное время которое должно пройти до того, как ответ устареет. Обе этих опции увеличивают ограничения на поведение кэшей, и, таким образом, не могут далее ослаблять уровень семантической прозрачности кэша.
Клиент может также указать, что он примет ответы, просроченные до некоторого определенного срока. Это ослабляет ограничения на кэши, и, таким образом, может нарушить ограничения на семантическую прозрачность, определенные первоначальным сервером, но может быть необходимо для поддержки раздельного функционирования, или высокой доступности при плохой связи.
13.2.1 Устаревание, указанное сервером.
HTTP кэширование работает лучше всего тогда, когда кэши могут полностью избежать запросов к первоначальному серверу. Первичный механизм избавления от запросов - когда сервер происхождения обеспечивает явное время устаревания в будущем, указывая, что ответ может использоваться для удовлетворения последующих запросов. Другими словами, кэш может возвращать свежий ответ без контакта с сервером.
Мы ожидаем, что серверы будут назначать явное время устаревания ответов будучи убеждены, что объект, вероятно, не будет изменен семантически значимым способом до истечения этого времени. Это обычно сохраняет семантическую прозрачность, если время устаревания тщательно выбрано сервером.
Механизм устаревания применяется только к ответам, полученным из кэша а не к непосредственным ответам, немедленно посланным запрашивающему клиенту.
Если первоначальный сервер хочет вынудить семантически прозрачный кэш проверять достоверность каждого запроса, он может явно указать время устаревания в прошлом. Это означает, что ответ всегда просрочен, и, таким образом, кэш должен проверять его достоверность перед использованием для последующих запросов.
Если первоначальный сервер хочет вынудить любой HTTP/1.1 кэш, независимо от того, как он сконфигурирован, проверять достоверность каждого запроса, он должен использовать директиву Cache-Control "must-revalidate".
Серверы указывают явное время устаревания, используя как заголовок Expires, так и директиву max-age заголовка Cache-Control.
Время устаревания не может использоваться чтобы вынудить агента пользователя обновить отображенную на экране информацию или перезагрузить ресурс; оно имеет значение только в применении к механизмам кэширования, и этим механизмам требуется только проверяет состояние устаревания ресурса, когда происходит новый запрос этого ресурса.
13.2.2 Эвристическое устаревание.
Так как первоначальные серверы не всегда указывают явное время устаревания, то HTTP кэши обычно назначают эвристическое время устаревания, используя алгоритмы, которые используют значения других заголовков (таких как время последней модификации (Last-Modified)) для оценки вероятного времени устаревания. Спецификация HTTP/1.1 не обеспечивает специфических алгоритмов, но налагает ограничения в виде оценки наихудшей погрешности их работы. Так как эвристическое временя устаревания может ставить под угрозу семантическую прозрачность, то они должны использоваться осторожно, и мы поощряем первоначальные серверы указывать явное время устаревания насколько возможно часто.
Чтобы знать, является ли содержащийся в кэше объект свежим, кэш должен знать, превышает ли его возраст срок свежести.
Хосты, которые используют HTTP, а в особенности хосты, на которых выполняются первоначальные серверы и кэши, должны использовать NTP или любой подобный протокол для синхронизации их часов с глобальным точным временем.
HTTP/1.1 требует, чтобы первоначальные серверы посылали в каждом ответе заголовок Date, предоставляющий время, когда был сгенерирован ответ.
HTTP/1.1 использует заголовок ответа Age для передачи информации о возрасте между кэшами. Значение заголовка Age является оценкой отправителя количества времени, прошедшего с момента, когда ответ был сгенерирован на первоначальном сервере. В случае кэшированного ответа, который был повторно подтвержден первоначальным сервером, значение Age базируется на времени перепроверки достоверности, а не на времени первоначального ответа.
В сущности, значение Age - сумма времен которые ответ находился в каждом из кэшей по пути от первоначального сервера и времен его передачи по сети.
Возраст ответа может быть вычислен двумя совершенно независимыми способами:
1. "Сейчас" минус date_value, если локальные часы хорошо синхронизированы с часами первоначального сервера. Если результат отрицателен, результат заменяется нулем.
2. age_value, если все кэши по пути ответа реализуют HTTP/1.1.
При условии, что мы имеем два независимых способа вычисления возраста ответа при его получении, мы можем объединить их как
Corrected_received_age = max("сейчас" - date_value, age_value)
и пока часы у нас синхронизированы, а все кэши на пути ответа - HTTP/1.1, получаем надежный (консервативный) результат.
Эта поправка применяется в каждом HTTP/1.1 кэше по пути следования ответа, так что если на пути встретится HTTP/1.0 кэш, то полученный возраст будет вычислен правильно, если часы этого кэша хорошо синхронизированы.
Из-за задержек, обусловленных сетью, некоторое значительное время может пройти между моментом, когда сервер сгенерировал ответ и моментом, когда он был получен следующим внешним кэшем или клиентом. Игнорирование этой задержки, приводить к неправильно низким возрастам.
Если запрос, который привел к возвращенному значению Age, должно быть был инициализирован до порождения значений Age, мы можем исправлять наложенные сетью задержки, делая запись времени, когда был сгенерирован запрос. Таким образом, когда получено значение Age, оно должно быть интерпретировано относительно времени, когда был сгенерирован запрос, а не относительно времени, когда был получен ответ. Этот алгоритм приводит к консервативному поведению независимо от того, какова задержка. Вычисляем:
corrected_initial_age = corrected_received_age + ("сейчас" - request_time)
Где "request_time" - время (согласно локальным часам), когда был послан запрос, вызвавший данный ответ.
Резюме алгоритма вычисления возраста полученного кэшем ответа:
/* * age_value * - это значение Age: заголовок, полученный кэшем в * этом ответе. * date_value * - это значение Date первоначального сервера: заголовок * request_time * - это (локальное) времея, когда кэш сделал запрос, * который вызвал этот кэшируемый ответ * response_time * - это (локальное) время, когда кэш получил ответ * now * - текущее (локальное) время */ apparent_age = max(0, response_time - date_value); corrected_received_age = max(apparent_age, age_value); response_delay = response_time - request_time; corrected_initial_age = corrected_received_age + response_delay; resident_time = now - response_time; current_age = corrected_initial_age + resident_time;
Когда кэш посылает ответ, он должен добавить к corrected_initial_age количество времени, которое ответ содержался в нем. Он должен затем передать этот общий возраст, используя заголовок Age, следующему получающему кэшу.
13.2.4 Вычисление устаревания.
Чтобы решить,является ли ответ свежим или просроченным, мы должны сравнить срок его службы с возрастом. Возраст вычисляется по алгоритму, описанному в разделе 13.2.3, а этот раздел описывает, как вычислять срок службы, и определять, не устарел ли ответ. В следующем описании значения могут представляться в любой форме, подходящей для арифметических действий.
Термин "expires_value" представляет значение заголовка Expires. Термин "max_age_value" применяется для указания значения числа секунд, представленного директивой max-age заголовка Cache-Control ответа.