Правила того, когда использовать метки объекта и даты последней модификации
Мы принимаем набор правил и рекомендаций для исходных серверов, клиентов и кэшей относительно того, когда должны использоваться различные типы валидаторов и для каких целей.
Исходный сервер HTTP/1.1:
должен послать валидатор метки объекта, если только возможно его сгенерировать;
может послать слабую метку объекта вместо сильной, если рабочие соображения поддерживают использования слабых меток объекта или если невозможно послать сильную метку объекта;
должен послать значение Last-Modified, когда это возможно, если только риск нарушения семантической прозрачности, которое может явиться следствием использования этой даты в заголовке, не приведет к серьезным проблемам.
Другими словами, предпочтительным поведением для исходного сервера HTTP/1.1 является посылка сильной метки объекта и значения Last-Modified.
Для сохранения легальности сильная метка объекта должна изменяться всякий раз, когда каким-либо образом меняется ассоциированное значение объекта. Слабую метку объекта следует менять всякий раз, когда соответствующий объект изменяется семантически значимым образом.
Для того, чтобы обеспечить семантически прозрачное кэширование, исходный сервер должен избегать повторного использования специфических, сильных меток для двух разных объектов или повторного использования специфических, слабых меток для двух семантически разных объектов. Записи в кэш могут существовать сколь угодно долгое время вне зависимости от времени годности. Таким образом, может оказаться неразумным ожидать, что кэш никогда вновь не попытается перепроверить запись, используя валидатор, который он получил в какойто момент в прошлом.
Клиенты HTTP/1.1
Если метка объекта была прислана исходным сервером, эта метка должна быть использована в любом условном запросе кэша (с If-Match или If-None-Match ).
Если только значение Last-Modified было прислано исходным сервером, оно должно использоваться в нефрагментных, условных запросах кэша (с использованием If-Modified-Since ).
Если только значение Last-Modified было прислано исходным сервером HTTP/1.0, оно может использоваться в фрагментных, условных запросах кэша (с использованием If-Unmodified-Since:). Агенту пользователя следует обеспечить способ блокировки этого в случае возникновения трудностей.
Если и метка объекта и значение Last-Modified были присланы исходным сервером, в условных запросах кэша следует использовать оба валидатора. Это позволяет корректно реагировать кэшам, поддерживающим как HTTP/1.0, так и HTTP/1.1.
Кэш HTTP/1.1 при получении запроса должен использовать наиболее регламентирующий валидатор, когда проверяется, соответствуют ли друг другу запись в буфере клиента и запись в кэше. Это единственный выход, когда запрос содержит как метку объекта, так и валидатор lastmodifieddate ( If-Modified-Since или If-Unmodified-Since ).
Базовым принципом всех этих правил является то, что HTTP/1.1 серверы и клиенты должны пересылать как можно больше надежной информации в своих запросах и откликах. HTTP/1.1 системы, принимая эту информацию, используют наиболее консервативное предположение относительно валидаторов, которые они получают.
Условия пригодности
Принцип использования меток объектов базируется на том, что только автор услуг знает семантику ресурсов достаточно хорошо, чтобы выбрать подходящий механизм контроля кэширования. Спецификация любой функции сравнения валидаторов более сложна, чем сравнение байтов. Таким образом, для целей проверки пригодности записи в кэше никогда не используется сравнение любых других заголовков кроме Last-Modified, для совместимости с HTTP/1.0.
Кэшируемость отклика
Если только нет специального ограничения директивой Cache-Control, система кэширования может всегда запоминать отклик в виде записи в кэш, может прислать его без проверки пригодности, если он является свежим, и может отослать его после успешной проверки пригодности. Если нет ни валидатора кэша, ни времени пригодности, ассоциированного с этим откликом, такой отклик может не кэшироваться, но некоторые кэши могут нарушить это правило (например, когда имеется плохая коннективность или она вообще отсутствует). Клиент обычно может детектировать, что такой отклик был взят из кэша, после сравнения заголовка Date с текущим временем.
Заметьте, что некоторые кэши HTTP/1.0 нарушают эти правила, даже не присылая предупреждения.
Однако в некоторых случаях для кэша может быть неприемлемо сохранять объект или присылать его в ответ на последующие запросы. Возможная причина: автор сервиса полагает необходимой абсолютную семантическую прозрачность по соображениям безопасности или конфиденциальности. Определенные директивы Cache-Control предназначены для того, чтобы сервер мог указать, что некоторые объекты ресурсов или их части не могут кэшироваться ни при каких обстоятельствах.
Заметьте, что в нормальной ситуации кэшу запрещено запоминать и отсылать отклик на предыдущий запрос, если этот запрос включает в себя заголовок авторизации. Но полагаться на это не следует.
Отклик, полученный со статусным кодом 200, 203, 206, 300, 301 или 410, может быть запомнен кэшем и использован в ответе на последующие запросы, если директива не препятствует кэшированию. Однако кэш, который не поддерживает заголовки Range и ContentRange, не должен кэшировать отклики 206 (Partial Content).
Отклик, полученный с любым другим статусным кодом, не должен отсылаться в ответ на последующие запросы, если только нет директив Cache-Control или других заголовков, которые напрямую разрешают это. К таким, например, относятся: заголовок Expires; maxage, mustrevalidate, proxyrevalidate, public или private директива Cache-Control.
Формирование откликов кэшей
Целью кэша HTTP является запоминание информации, полученной в откликах на запросы, для использования в ответ на будущие запросы. Во многих случаях кэш просто отсылает соответствующие части отклика отправителю запроса. Однако если кэш содержит объект, базирующийся на предшествующем отклике, он может быть вынужден комбинировать части нового отклика с тем, что хранится в объекте кэша.
Заголовки End-to-end (точкаточка) и Hop-by-hop (шагза-шагом)
Для определения поведения кэшей и некэширующих проксисерверов заголовки HTTP делят на две категории.
Заголовки End-to-end, которые должны быть пересланы конечному получателю запроса или отклика. Такие заголовки в откликах должны запоминаться как часть объекта кэша и пересылаться в любом отклике, полученном из записи кэша.
Заголовки Hop-by-hop, которые имеют смысл только для одноуровневого транспортного соединения, они не запоминаются кэшем и не переадресуются проксисерверами.
Следующие заголовки HTTP/1.1 относятся к категории hop-by-hop:
Connection
Keep-Alive
Public
Proxy-Authenticate
Transfer-Encoding
Upgrade
Все другие заголовки, определенные HTTP/1.1, относятся к категории end-to-end. Заголовки Hop-by-hop должны быть перечислены в заголовке Connection.
Немодифицируемые заголовки
Некоторые черты протокола HTTP/1.1, такие, как Digest Authentication, зависят от значения определенных заголовков end-to-end. Кэш или некэширующий прокси не должны модифицировать заголовок end-to-end, если только определение этого заголовка не требует или не разрешает этого.
Кэш или некэширующий прокси не должны модифицировать любое из следующих полей запроса или отклика или добавлять какие-либо поля, если они еще не существуют:
Content-Location
Etag
Expires
Last-Modified
Кэш или некэширующий прокси не должны модифицировать или добавлять следующие поля в любых запросах и в откликах, которые содержат директиву notransform Cache-Control:
Content-Encoding
Content-Length
Content-Range
Content-Type
Кэш или некэширующий прокси могут модифицировать или добавлять эти поля в отклик, который не включает директиву notransform. Если же он содержит эту директиву, следует добавить предупреждение 14 (Transformation applied) (если оно еще не занесено в отклик).
Комбинирование заголовков
Когда кэш делает запрос серверу о пригодности ресурса и сервер выдает отклик 304 (Not Modified), кэш должен подготовить и отправить отклик, чтобы послать клиенту. Кэш использует тело объекта из записи в кэше при формировании отклика. Заголовки end-to-end, записанные в кэше, используются для конструирования отклика. Исключение составляют любые end-to-end заголовки, поступившие в рамках отклика 304, — они должны заместить соответствующие заголовки из записи в кэше. Если только кэш не решил удалить запись, он должен также заменить end-to-end заголовки своей записи соответствующими заголовками из полученного отклика.
Другими словами, набор end-to-end заголовков, полученный вместе с откликом, переписывает все соответствующие end-to-end заголовки из записи в кэше. Кэш может добавить к этому набору заголовки предупреждений.
Если имя поля заголовка приходящего отклика соответствует более чем одной записи в кэше, все старые заголовки заменяются.
Замечание. Это правило позволяет исходному серверу использовать отклик 304 (Not Modified) для актуализации любого заголовка, связанного с предыдущим откликом для того же объекта, хотя это может не всегда иметь смысл. Это правило не позволяет исходному серверу использовать отклик 304 (not Modified) для того, чтобы полностью стереть заголовок, который был прислан предыдущим откликом.