Unspecified end-to-end revalidation
Запрос включает в себя директиву управления кэшем max-age=0, которая вынуждает каждый кэш вдоль пути к исходному серверу сверить свою собственную запись с записью следующего кэша или сервера. Исходный запрос не включает в себя требований перепроверки. Первый кэш по пути (если таковой имеется), который содержит запись данного ресурса, подключает условия перепроверки со своим текущим валидатором.
Когда промежуточный кэш вынуждается с помощью директивы max-age=0 перепроверить свои записи, присланный клиентом валидатор может отличаться от того, что записан в данный момент в кэше. В этом случае кэш может воспользоваться в своем запросе любым из валидаторов, не нарушая семантической прозрачности.
Однако выбор валидатора может влиять на результат. Наилучшим подходом для промежуточного кэша является использование в запросе своего собственного валидатора. Если сервер присылает отклик 304 (Not Modified), то кэш должен отправить свою уже проверенную копию клиенту со статусным кодом 200 (OK). Если сервер присылает отклик с новым объектом и валидатором кэша, промежуточный кэш должен сверить, тем не менее, полученный валидатор с тем, что прислал клиент, используя функцию сильного сравнения. Если валидатор клиента равен присланному сервером, то промежуточный кэш просто возвращает код 304 (Not Modified). В противном случае он присылает новый объект со статусным кодом 200 (OK).
Если запрос включает в себя директиву no-cache, в нем не должно быть minfresh, max-stale или maxage.
В некоторых случаях, таких, как периоды исключительно плохой работы сети, клиент может захотеть возвращать только те отклики, которые в данный момент находятся в памяти, и не перезагружать или перепроверять записи из исходного сервера. Для того, чтобы сделать это, клиент может включить в запрос директиву only-if-cached. При получении такой директивы кэшу следует либо реагировать, используя кэшированную запись, которая соответствует остальным требованиям запроса, либо откликаться статусным кодом 504 (Gateway Timeout). Однако если группа кэшей работает как унифицированная система с хорошей внутренней коннективностью, тогда такой запрос может быть переадресован в пределах группы кэшей
Поскольку кэш может быть сконфигурирован так, чтобы игнорировать времена жизни, заданные сервером, а запрос клиента может содержать директиву maxs-tale, протокол включает в себя механизм, который позволяет серверу требовать перепроверки записей в кэше для любого последующего применения. Когда в отклике, полученном кэшем, содержится директива must-revalidate, этот кэш не должен использовать эту запись для откликов на последующие запросы без сверки ее на исходном сервере. Таким образом, кэш должен выполнить перепроверку end-to-end каждый раз, если согласно значениям Expires или maxage кэшированный отклик является устаревшим.
Директива mustrevalidate необходима для поддержания надежной работы для определенных функций протокола. При любых обстоятельствах HTTP/1.1 кэш должен выполнять директиву mustrevalidate. В частности, если кэш по какой-либо причине не имеет доступа к исходному серверу, он должен генерировать отклик 504 (Gateway Timeout).
Серверы должны посылать директиву mustrevalidate тогда и только тогда, когда неудача запроса перепроверки объекта может вызвать нарушение работы системы, например, невыполнение финансовой операции без оповещения об этом. Получатели не должны осуществлять любые автоматические действия, которые нарушают эту директиву, и не должны посылать непригодную копию объекта, если перепроверка не удалась.
Хотя это и не рекомендуется, агенты пользователя, работающие в условиях очень плохой коннективности, могут нарушать эту директиву, но, если это происходит, пользователь должен быть предупрежден в обязательном порядке, что присланный отклик, возможно, является устаревшим. Предупреждение должно посылаться в случае каждого непроверенного доступа, при этом следует требовать подтверждения от пользователя.
Директива proxyrevalidate имеет то же значение, что и mustrevalidate, за исключением того, что она неприменима для индивидуальных кэшей агентов пользователя. Она может применяться в отклике на подтвержденный запрос, чтобы разрешить кэшу пользователя запомнить и позднее прислать отклик без перепроверки (так как он был уже подтвержден однажды этим пользователем), в то же время прокси должен требовать перепроверки всякий раз при обслуживании разных пользователей (чтобы быть уверенным, что каждый пользователь был авторизован). Заметьте, что такие авторизованные отклики нуждаются также в директиве управления кэшем public, чтобы разрешить их кэширование.
Директива No-Transform
Разработчики промежуточных кэшей (прокси) выяснили, что полезно преобразовать тип среды для тел определенных объектов. Прокси может, например, преобразовать форматы изображения для того, чтобы сэкономить место в памяти кэша или чтобы уменьшить информационный поток в тихоходном канале. HTTP должен датировать такие преобразования, выполняемые без оповещения.
Серьезные операционные проблемы происходят, однако, когда такие преобразования производятся над телами объектов, предназначенных для определенного сорта приложений: например, для приложений, использующих медицинские изображения, предназначенные для анализа научных данных, а также тех, которые применяют авторизацию endtoend или требуют побитной совместимости с оригиналом.
Следовательно, если отклик содержит директиву no-transform, промежуточный кэш или прокси не должны изменять те заголовки, так как они могут содержать директиву no-transform. Это предполагает, что кэш или прокси не должны изменять любую часть тела объекта, который имеет такие заголовки.
Расширения управления кэшем
Поле заголовка Cache-Control может быть расширено за счет использования одной или более лексем расширения, каждой из которых может быть присвоено определенное значение. Информационные расширения (те, которые не требуют изменений в работе кэша) могут быть добавлены без изменения семантики других директив. Поведенческие расширения спроектированы для того, чтобы выполнять функции модификаторов существующих директив управления кэшем. Новые директивы и стандартные директивы устроены так, что приложения, которые не воспринимают новую директиву, по умолчанию исполнят стандартную процедуру. Те же приложения, которые распознают новую директиву, воспринимают ее как модификацию стандартной процедуры. Этот способ дает возможность расширить директивы управления кэшем без изменения базового протокола.
Этот механизм расширений зависит от того, выполняет ли кэш все директивы управления, определенные для базовой версии HTTP. Предполагается, что кэш реализует определенные расширения и игнорирует все директивы, которые не может распознать.
Например, рассмотрим гипотетическую новую директиву, названную community, которая действует как модификатор директивы private. Мы определяем эту новую директиву так, что, в дополнение к стандартным возможностям индивидуальных кэшей, кэши, которые обслуживают группу (community), могут кэшировать их отклики. Исходный сервер, желающий позволить группе UCI использовать частные отклики на их общем кэше, может решить эту проблему, включив директиву управления кэшем: private, community=UCI.
Кэш, получив это поле заголовка, будет действовать корректно, если даже не понимает расширение community, так как он видит и понимает директиву private и, таким образом, по умолчанию обеспечит безопасное функционирование.
Нераспознанная директива управления должна игнорироваться. Предполагается, что любая директива, в том числе и не узнанная кэшем, имеет по умолчанию стандартную директивуподмену, которая обеспечивает определенный уровень функциональности, когда директиварасширение не распознается.
Соединение
Поле общего заголовка Connection позволяет отправителю специфицировать опции, которые желательны для конкретного соединения. Заголовок Connection имеет следующую грамматику:
Connectionheader = "Connection" ":" 1#(connectiontoken)
connectiontoken = token
Проксисерверы HTTP/1.1 должны выполнить разбор поля заголовка Connection, прежде чем выполнить переадресацию, и для каждой лексемы соединения в этом поле убрать любые поля заголовка в сообщении с именами, совпадающими с этими лексемами. Опции Connection отмечаются присутствием лексем соединения в поле заголовка Connection, а не какимилибо дополнительными полями заголовка, так как дополнительное поле заголовка может быть не послано, если нет параметров, ассоциированных с данной опцией соединения. HTTP/1.1 определяет опцию close (закрыть) для отправителя, чтобы сигнализировать о том, что соединение будет закрыто после завершения передачи отклика. Например, наличие
Connection: close
как в полях запроса, так и в полях отклика указывает на то, что соединение не следует рассматривать как постоянное после завершения передачи данного запроса/отклика.
Приложения HTTP/1.1, которые не поддерживают постоянные соединения, должны содержать опцию соединения close в каждом сообщении.
Content-Base
Поле заголовка объекта ContentBase может быть использовано для спецификации базового URI, которое позволяет работать с относительными URL в пределах объекта. Это поле заголовка описано как Base в документе RFC-1808.
ContentBase = "ContentBase" ":" absoluteURI
Если поле ContentBase отсутствует, базовый URI объекта определяется его ContentLocation (если это ContentLocation URI является абсолютным) или URI используется для инициации запроса. Заметьте, однако, что базовый URI содержимого в пределах тела объекта может быть переопределен.
Кодирование содержимого
Поле заголовка объекта Content-Encoding применяется в качестве модификатора типа среды. Если это поле присутствует, его значение указывает, что тело объекта закодировано, и какой механизм декодирования следует применить, чтобы получить массив данных, ориентированный на тип среды, который указан в поле Content-Type. Поле Content-Encodingпервоначально предназначалось для того, чтобы архивировать документ без потери его идентичности с учетом типа среды, на которую он ориентирован.
Content-Encoding = "Content-Encoding" ":" 1#contentcoding
Пример кодировки использования приведен ниже:
Content-Encoding: gzip
Content-Encoding (кодирование содержимого) является характеристикой объекта, задаваемой Request-URI. Обычно тело объекта заносится в память в закодированном виде и декодируется перед отображением или другим аналогичным использованием.
Если было применено множественное кодирование объекта, кодирование содержимого должно быть перечислено в том порядке, в котором оно было выполнено.
Язык содержимого
Поле заголовка объекта ContentLanguage описывает естественный язык(и) потенциальных читателей вложенного объекта. Заметьте, что это может быть совсем не эквивалентно всем языкам, использованным в теле объекта.
ContentLanguage = "ContentLanguage" ":" 1#languagetag
Первоначальной целью поля ContentLanguage является предоставление пользователю возможности дифференцировать объекты согласно языковым предпочтениям. Таким образом, если содержимое тела предназначено только для аудитории, говорящей на датском языке, подходящим содержимым поля ContentLanguage может быть
ContentLanguage: da
Если поле ContentLanguage не задано, по умолчанию считается, что содержимое ориентировано на любую аудиторию. Это может означать, что отправитель не выделяет какойлибо естественный язык конкретно или что отправитель не знает, какой язык предпочесть.
Список языков может быть предложен для текста, который предназначен для многоязыковой аудитории. Например, перевод "Treaty of Waitangi", представленный одновременно в оригинальной версии на маори и на английском, может быть вызван с помощью
ContentLanguage: mi, en
Однако только то, что в поле объекта перечислено несколько языков не означает, что объект предназначен для многоязыковой аудитории. Примером может быть языковый курс для начинающих, такой, как "A First Lesson in Latin", который предназначен для англоговорящей аудитории. В этом случае поле ContentLanguage должно включать только en.
Поле ContentLanguage может быть применено к любому типу среды — оно не ограничено только текстовыми документами.
Длина содержимого
Содержимое поля заголовка объекта ContentLength указывает длину тела сообщения в октетах (десятичное число), посылаемое получателю, или в случае метода HEAD — размер тела объекта, который мог бы быть послан при запросе GET.
ContentLength = "ContentLength" ":" 1*DIGIT
Например:
ContentLength: 3495
Приложениям следует использовать это поле для указания размера сообщения, которое должно быть послано, вне зависимости от типа среды. Получатель должен иметь возможность надежно определить положение конца запроса HTTP/1.1, содержащего тело объекта, например, запрос использует Transfer-Encoding chunked или multipart body. Любое значение ContentLength, большее или равное нулю, допустимо.
Замечание. Значение этого поля заметно отличается от соответствующего определения в MIME, где оно является опционным, используемым в типе содержимого message/externalbody. В HTTP его следует посылать всякий раз, когда длина сообщения должна быть известна до начала пересылки.
Поле Content-Location
Поле заголовка объекта Content-Location может быть применено для определения положения ресурса для объекта, вложенного в сообщение. В случае, когда ресурс содержит много объектов и эти объекты в действительности имеют разные положения, по которым может быть осуществлен доступ, сервер должен предоставить поле Content-Location для конкретного варианта, который должен быть прислан. Кроме того, сервер должен предоставить Content-Location для ресурса, соответствующего объекту отклика.
Content-Location = "Content-Location" ":"
( absoluteURI | relative-URI )
Если поле заголовка Content-Base отсутствует, значение Content-Location определяет также базовый URL для объекта.
Значение Content-Location не является заменой для исходного запрашиваемого URI, это лишь объявление положения ресурса, соответствующего данному конкретному объекту в момент запроса. Будущие запросы могут использовать Content-Location URI, если нужно идентифицировать источник конкретного объекта.
Кэш не может предполагать, что объект с полем Content-Location, отличающимся от URI, который применялся для его получения, может использоваться для откликов на последующие запросы к этому Content-Location URI. Однако Content-Location может быть нужен для того, чтобы отличить объекты, полученные из одного общего ресурса.
Если Content-Location является относительным URI, URI интерпретируется с учетом значения Content-Base URI, присланного в отклике. Если значения ContentBase не предоставлено, относительный URI интерпретируется по отношению к Request-URI.
Content-MD5
Поле заголовка объекта Content-MD5, как это определено в RFC-1864 [7.23], является MD5-дайджестом тела объекта для целей обеспечения проверки end-to-end целостности сообщения MIC (Message Integrity Check). Проверка MIC привлекательна для регистрации случайных модификаций тела объекта при транспортировке, но не является гарантией против преднамеренных действий.
Content MD5 = "ContentMD5" ":" md5digest
md5digest = <base64 of 128 bit MD5 digest as per RFC-1864>
Поле заголовка Content-MD5 может генерироваться исходным сервером с целью проверки целостности тел объектов. Только исходные серверы могут генерировать поле заголовка Content-MD5. Прокси и внешние шлюзы его генерировать не должны, так как это сделает невозможными проверку целостности end-to-end. Любой получатель тела объекта, включая внешние шлюзы и прокси, могут проверять то, что значение дайджеста в этом поле заголовка согласуется с полученным телом объекта.
Дайджест MD5 вычисляется на основе содержимого тела сообщения, с учетом любых кодировок содержимого, но исключая любые транспортные кодировки ( Transfer-Encoding ), которые могли быть применены. Если сообщение получено в закодированном виде с использованием Transfer-Encoding, это кодирование должно быть удалено перед проверкой значения Content-MD5 для полученного объекта.
Это означает, что дайджест вычисляется для октетов тела объекта в том порядке, в каком они будут пересланы, если не применяется транспортное кодирование.
HTTP расширяет RFC-1864 с тем, чтобы разрешить вычисление дайджеста для MIME-комбинации типов среды (например, multipart/* и message/rfc-822 ), но это никак не влияет на способ вычисления дайджеста, описанного выше.
Замечание. Существует несколько следствий этого. Тело объекта для комбинированных типов может содержать много составных частей, каждая со своими собственными MIME и HTTP заголовками (включая заголовки Content-MD5, ContentTransfer-Encoding и Content-Encoding ). Если часть тела имеет заголовок ContentTransfer-Encoding или Content-Encoding, предполагается, что содержимое этой части закодировано, и оно включается в дайджест Content-MD5как есть. Поле заголовка Transfer-Encoding не применимо для частей тела объекта.
Так как определение Content-MD5 является в точности таким же для HTTP и для MIME (RFC-1864), существует несколько вариантов, в которых применение ContentMD5 к телам объектов HTTP отличается от случая MIME. Один вариант связан с тем, что HTTP, в отличие от MIME, не использует ContentTransfer-Encoding, а применяет Transfer-Encoding и Content-Encoding. Другой вызван тем, что HTTP чаще, чем MIME, использует двоичный тип содержимого. И, наконец, HTTP позволяет передачу текстовой информации с любым типом разрыва строк, а не только с каноническим CRLF. Преобразование всех разрывов строк к виду CRLF не должно делаться до вычисления или проверки дайджеста: тип оформления разрыва строк при расчете дайджеста должен быть сохранен.
Отрывок содержимого
Заголовок объекта ContentRange посылается с частью тела объекта и служит для определения того, где в теле объекта должен размещаться данный фрагмент. Он также указывает полный размер тела объекта. Когда сервер присылает клиенту частичный отклик, заголовок должен описать как длину фрагмента, так и полный размер тела объекта.
Content-Range = "Content-Range" ":" content-range-spec
Content-range-spec = byte-content-range-spec
byte-content-range-spec = bytesunit SP firstbytepos ""
last-byte-pos "/" entitylength
entitylength = 1*DIGIT
-
В отличие от значений спецификаторов байтовых диапазонов ( byte-ranges-specifier ), bytecontentrangespec может специфицировать только один интервал и должен содержать абсолютные положения, как первого, так и последнего байтов.
Некорректной считается спецификация byte-content-range-spec, чье значение last-byte-pos меньше, чем его значение first-byte-pos, либо значение длины объекта меньше или равно last-byte-pos. Получатель некорректной спецификации byte-content-range-spec должен игнорировать ее и любой текст, переданный вместе с ней. Примеры спецификации byte-content-range-spec, предполагающей, что объект содержит 1234 байт, приведены ниже.
The first 500 bytes (первые 500 байт): bytes 0-499/1234
The second 500 bytes (следующие 500 байт): bytes 500-999/1234
All except for the first 500 bytes (все кроме первых 500 байт): bytes 5001233/1234
The last 500 bytes (последние 500 байт): bytes 734-1233/1234
Когда сообщение HTTP включает в себя содержимое одного фрагмента (например, отклик на запрос одного фрагмента или на запрос набора фрагментов, которые перекрываются без зазоров), это содержимое передается с заголовком Content-Range, а заголовок Content-Length несет в себе число действительно переданных байт. Например,
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Lastmodified: Wed, 15 Nov 1995 04:58:08 GMT
ContentRange: bytes 2101047021/47022
ContentLength: 26012
Content-Type: image/gif
Когда сообщение HTTP заключает в себе содержимое нескольких фрагментов (например, отклик на запрос получения нескольких, не перекрывающихся фрагментов), они передаются как многофрагментное MIMEсообщение. Многофрагментный тип данных MIME, используемый для этой цели, определен в этой спецификации как multipart/byteranges.
Клиент, который не может декодировать сообщение MIME multipart/byteranges, не должен запрашивать несколько байтфрагментов в одном запросе.
Когда клиент запрашивает несколько фрагментов байт в одном запросе, серверу следует присылать их в порядке перечисления.
Если сервер игнорирует спецификацию byte-range-spec, изза того, что она некорректна, сервер должен воспринимать запрос так, как если бы некорректного заголовка Range не существовало вовсе. В нормальной стуации это означает посылку отклика с кодом 200, содержащего весь объект. Причина в том, что клиент может прислать такой некорректный запрос, только когда объект меньше, чем объект, полученный по предыдущему запросу.
Тип содержимого
Поле заголовка объекта Content-Type указывает тип среды тела объекта, посланного получателю, или, в случае метода HEAD, тип среды, который был бы применен при методе GET.
Content-Type = "Content-Type" ":" mediatype
Примером поля может служить
Content-Type: text/html; charset=ISO88594
Дата
Поле общего заголовка Date представляет дату и время формирования сообщения, имеет ту же семантику, что и origdate в RFC-822. Значение поля равно HTTP-date.
Date = "Date" ":" HTTPdate
Пример
Date: Tue, 15 Nov 1994 08:12:31 GMT
Если сообщение получено через непосредственное соединение с агентом пользователя (в случае запросов) или исходным сервером (в случае откликов), дата может считаться текущей датой конца приема. Однако, так как дата по определению является важной при оценке характеристик кэшированных откликов, исходный сервер должен включать поле заголовка Date в каждый отклик. Клиентам следует включать поле заголовка Date в сообщения, которые несут тело объекта запросов PUT и POST, но даже здесь это является опционным. Полученному сообщению, которое не имеет поля заголовка Date, следует присвоить дату. Это может сделать один из получателей, если сообщение будет кэшировано им или внешним шлюзом.
Теоретически дата должна представлять момент времени сразу после генерации объекта. На практике поле даты может быть сформировано в любое время в процессе генерации сообщения.
Формат поля Date представляет собой абсолютную дату и время так, как это определено для даты HTTP. Оно должно быть послано в формате, описанном в документе RFC-1123 [7.8].
Поле ETag
Поле заголовка объекта ETag определяет метку объекта. Метка объекта может использоваться для сравнения с другими объектами того же самого ресурса.
ETag = "ETag" ":" entitytag
Примеры:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
Поле Expires
Поле заголовка объекта Expires содержит дату/время с момента, когда отклик может считаться устаревшим. Устаревшая запись в кэше в нормальной ситуации не должна посылаться кэшем (а также прокси кэшем и кэшем агента пользователя), если только она не будет сначала перепроверена с помощью исходного сервера (или с помощью промежуточного кэша, который содержит свежую копию объекта). Присутствие поля Expires не предполагает, что исходный ресурс изменит или удалит объект по истечении указанного времени.
Формат абсолютной даты и времени должен следовать рекомендациям документа RFC-1123:
Expires = "Expires" ":" HTTPdate
Примером реализации формата даты может служить
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Замечание. Если отклик содержит поле Cache-Control с директивой maxage, то эта директива переписывает значение поля Expires.
Клиенты HTTP/1.1 и кэши должны рассматривать некорректные форматы даты, в особенности те, что содержат нули, как относящиеся к прошлому (то есть, как уже истекшие).
Для того, чтобы пометить отклик, как "уже с истекшим сроком", исходный сервер должен использовать дату Expires, которая равна значению заголовка Date.
Для того, чтобы пометить отклик как всегда пригодный, исходный сервер должен использовать дату Expiresприблизительно на один год позже момента посылки отклика. Серверы HTTP/1.1 не должны посылать отклики с датами в поле Expires, которые устанавливают время жизни более одного года.
Присутствие поля заголовка Expires со значением даты, относящейся к будущему, означает, что они могут быть занесены в кэш, если только не указано обратного в поле заголовка Cache-Control.
Поле From
Поле заголовка запроса From (если присутствует) должно содержать интернетовский email адрес пользователя. Адрес должен иметь формат, описанный в документе RFC-822 (и дополненный в RFC-1123):
From = "From" ":" mailbox
Пример:
From: [email protected]
Это поле заголовка может быть применено для целей регистрации процедур и как средство идентификации источников некорректных и нежелательных запросов. Не следует использовать его как ненадежную систему защиты доступа. Это поле предоставляет информацию о том, кто является ответственным за метод, использованный в данном запросе. В частности, агентыроботы должны содержать этот заголовок, чтобы с лицом, ответственным за работу робота, можно было связаться в случае возникновения проблем на принимающем конце.
Интернетовский e-mail адрес в этом поле может не совпадать с Интернетадресом ЭВМ, пославшей запрос. Например, когда запрос прошел через прокси, следует использовать адрес первичного отправителя.
Клиенту не следует посылать поле заголовка From без одобрения пользователя, так как это может вызвать конфликт с интересами конфиденциальности пользователя или нарушить политику безопасности сети отправителя. Настоятельно рекомендуется, чтобы пользователь мог дезактивировать, активировать и модифицировать значение этого поля в любое время до запроса.
Поле Host
Поле заголовка запроса Host специфицирует ЭВМ в Интернет и номер порта запрашиваемого ресурса в виде, полученном из исходного URL, который выдал пользователь или который получен из указанного ресурса (в общем случае из HTTP URL). Значение поля Host должно определять положение в сети исходного сервера или шлюза, заданное исходным URL. Это позволяет исходному серверу или шлюзу различать внутренние URL, такие, как корневые "/" URL сервера для ЭВМ, которым поставлен в соответствие один IP адрес.
Host = "Host" ":" host [ ":" port ] ;
Имя ЭВМ без последующего номера порта предполагает значение порта по умолчанию для заданного вида сервиса (напр., 80 для HTTP URL). Например, запрос исходного сервера должен включать в себя:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org
Клиент должен вносить поле заголовка Host во все сообщениязапросы HTTP/1.1 в Интернет (т.е., в любое сообщение, соответствующее запросу URL, который включает в себя Интернетадрес ЭВМ, чьи услуги запрашиваются). Если поле Host отсутствует, прокси HTTP/1.1 должен добавить его в сообщениезапрос до того, как переадресует запрос дальше в Интернет. Все серверы HTTP/1.1, которые базируются в Интернет, должны откликаться статусным кодом 400 на любое сообщениезапрос HTTP/1.1, в котором отсутствует поле Host.
Поле If-Modified-Since
Поле заголовка запроса If-Modified-Since используется с методом GET, для того чтобы сделать его условным. Если запрошенный объект не был модифицирован со времени, указанного в этом поле, объект не будет прислан сервером, — вместо этого будет послан отклик 304 (not modified) без какоголибо тела сообщения.
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
Пример поля:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Метод GET с заголовком If-Modified-Since и без заголовка Range требует, чтобы идентифицированный объект был передан, только в случае его модификации после даты, указанной в заголовке If-Modified-Since. Алгоритм определения этого включает в себя следующие шаги.
a. Если запрос приводит к чемуто отличному от статусного отклика 200 (OK), или если переданная дата If-Modified-Sinceнекорректна, отклик будет в точности тот же, что и для обычного GET. Дата раньше текущего времени сервера является некорректной.
b. Если объект был модифицирован после даты If-Modified-Since, отклик будет в точности тем же, что и для обычного GET.
c. Если объект не был модифицирован после корректно указанной даты If-Modified-Since, сервер должен прислать отклик 304 (Not Modified).
Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками.
Заметьте, что поле заголовка запроса Range модифицирует значение If-Modified-Since. Время If-Modified-Sinceинтерпретируются сервером, чьи часы могут быть не синхронизованы с часами клиента.
Если клиент использует произвольную дату в заголовке If-Modified-Since вместо даты, взятой из заголовка Last-Modified для текущего запроса, тогда клиенту следует остерегаться того, что эта дата интерпретируется согласно представлениям сервера о временной шкале. Клиенту следует учитывать несинхронность часов и проблемы округления, связанные с различным кодированием времени клиентом и сервером. Это предполагает возможность быстрого изменения условий, когда документ изменяется между моментом первого запроса и датой If-Modified-Since последующего запроса, а также возможность трудностей, связанных с относительным сбоем часов, если дата If-Modified-Since получена по часам клиента (без поправки на показания часов сервера). Поправки для различных временных базисов клиента и сервера желательно делать с учетом времени задержки в сети.
Поле If-Match
Поле заголовка запроса If-Match используется для того, чтобы сделать метод условным. Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, является ли один из этих объектов текущим, включив список связанных с ним меток в поле заголовка If-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками. Она применяется также в запросах актуализации с целью предотвращения непреднамеренной модификации не той версии ресурса, что нужна. Значение "*" соответствует любому текущему объекту ресурса.
If-Match = "If-Match" ":" ( "*" | 1#entitytag )
Если какаято метка объекта совпадает с меткой объекта, который прислан в отклике на аналогичный запрос GET (без заголовка If-Match ), или если задана "*" и какойто текущий объект существует для данного ресурса, тогда сервер может реализовать запрошенный метод, как если бы поля заголовка If-Match не существовало.
Сервер должен использовать функцию сильного сравнения для сопоставления меток объекта в If-Match.
Если ни одна из меток не подходит или если задана "*" и не существует никакого текущего объекта, сервер не должен реализовывать запрошенный метод, а должен прислать отклик 412 (Precondition Failed). Это поведение наиболее полезно, когда клиент хочет помешать актуализующему методу, такому, как PUT, модифицировать ресурс, который изменился после последнего доступа к нему клиента.
Если запрос без поля заголовка If-Match выдает в результате нечто отличное от статуса 2xx, то заголовок If-Matchдолжен игнорироваться.
"If-Match: *" означает, что метод должен быть реализован, если представление, выбранное исходным сервером (или кэшем, возможно с привлечением механизма Vary), существует, и не должен быть реализован, если выбранного представления не существует.
Запрос, предназначенный для актуализации ресурса (например, PUT), может включать в себя поле заголовка If-Match, чтобы сигнализировать о том, что метод запроса не должен быть применен, если объект, соответствующий значению If-Match (одиночная метка объекта), не является более представлением этого ресурса. Это позволяет пользователям указывать, что они не хотят, чтобы запрос прошел успешно, если ресурс был изменен без их уведомления. Примеры:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
Поле If-None-Match
Поле заголовка запроса If-None-Match используется для формирования условных методов. Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, что ни один из этих объектов не является текущим, путем включения списка их ассоциированных меток в поле заголовка If-None-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальной избыточностью. Она также применяется при актуализации запросов с тем, чтобы предотвратить непреднамеренную модификацию ресурса, о существовании которого не было известно.
Значение "*" соответствует любому текущему объекту ресурса.
If-None-Match = "If-None-Match" ":" ( "*" | 1#entitytag )
Если какая-либо метка объекта соответствует метке объекта, который был прислан в отклике на аналогичный запрос GET(без заголовка If-None-Match ), или если задана "*" и существует какойто текущий объект данного ресурса, то сервер не должен реализовывать запрошенный метод. Вместо этого, если методом запроса был GET или HEAD, серверу следует реагировать откликом 304 (Not Modified), включая поля заголовков объекта, ориентированные на кэш (в частности ETag ). Для всех других методов запроса сервер должен откликаться статусным кодом 412 (Precondition Failed).
С запросами GET и HEAD должна использоваться только функция слабого сравнения.
Если не подходит ни одна из меток объекта или если задана "*" и не существует ни одного текущего объекта, сервер может выполнить запрошенный метод так, как если бы поля заголовка If-None-Match не существовало.
Если запрос без поля заголовка If-None-Match, даст результат, отличный от статусного кода 2xx, тогда заголовок If-None-Match должен игнорироваться.
"If-None-Match: *" означает, что метод не должен реализовываться, если представление, выбранное исходным сервером (или кэшем, возможно использующим механизм Vary ), существует, и должен быть реализован, если представления не существует. Эта функция может быть полезной для предотвращения конкуренции между операциями PUT.
Примеры:
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
Заголовок If-Range
Если клиент имеет частичную копию объекта в своем кэше и хочет иметь полную свежую копию объекта, он может использовать заголовок запроса Range с условным GET (используя If-Unmodified-Since и/или If-Match.) Однако если условие не выполняется изза того, что объект был модифицирован, клиенту следует послать второй запрос, чтобы получить все текущее содержимое тела объекта.
Заголовок If-Range позволяет клиенту заблокировать второй запрос. По существу это означает, что "если объект не изменился, следует посылать мне часть, которой у меня нет, в противном случае пришлите мне всю новую версию объекта".
If-Range = "If-Range" ":" ( entitytag | HTTPdate )
Если клиент не имеет метки объекта, но имеет дату Last-Modified, он может использовать эту дату в заголовке If-Range. Сервер может отличить корректную дату HTTP от любой формы метки объекта, рассмотрев не более двух символов. Заголовок If-Range следует использовать только совместно с заголовком Range, и его следует игнорировать, если запрос не содержит в себе этот заголовок или если сервер не поддерживает операции с фрагментами.
Если метка объекта, представленная в заголовке If-Range, соответствует текущей метке, то сервер должен обеспечить специфицированный фрагмент объекта, применяя отклик 206 (Partial content). Если метка объекта не подходит, сервер должен прислать полный объект со статусным кодом 200 (OK).
Поле If-Unmodified-Since
Поле заголовка запроса If-Unmodified-Since применяется для того, чтобы формировать условные методы. Если запрошенный ресурс не был модифицирован с момента, указанного в поле, сервер должен произвести запрошенную операцию так, как если бы заголовок If-Unmodified-Since отсутствовал.
Если запрошенный объект был модифицирован после указанного времени, сервер не должен выполнять запрошенную операцию и должен прислать отклик 412 (Precondition Failed).
If-Unmodified-Since = "If-Unmodified-Since" ":" HTTPdate
Примером поля может служить:
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Если запрос завершается чемто отличным от статусного кода 2xx (т.е., без заголовка If-Unmodified-Since ), заголовок If-Unmodified-Since следует игнорировать. Если специфицированная дата некорректна, заголовок также игнорируется.
Поле Last-Modified
Поле заголовка объекта Last-Modified указывает на дату и время, при которых, по мнению исходного сервера, данный объект был модифицирован.
Last-Modified = "Last-Modified" ":" HTTPdate
Пример его использования
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Точное значение этого заголовка зависит от реализации исходного сервера и природы ресурса. Для файлов это может быть дата последней модификации файловой системы. Для объектов с динамическими встроенными частями — время последней модификации одной из встроенных компонент. Для шлюзов баз данных — метка последней модификации рекорда. Для виртуальных объектов — время последнего изменения внутреннего состояния.
Исходный сервер не должен посылать дату Last-Modified, более позднюю, чем время формирования сообщения сервера. В таких случаях, когда последняя модификация объекта указывает на некоторое время в будущем, с<