Примеры сетевых топологий

         

Определения полей заголовка


Этот раздел определяет синтаксис и семантику всех стандартных полей заголовков HTTP/1.1. Для полей заголовков объекта, как отправитель, так и получатель могут рассматриваться клиентом или сервером в зависимости от того, кто получает объект.

13.1. Поле Accept

Поле заголовка запроса Accept может использоваться для спецификации определенных типов среды, которые приемлемы для данного ресурса. Заголовки Accept могут использоваться для индикации того, что запрос ограничен в рамках определенного набора типов, как в случае запросов отображения в текущей строке.

Accept = "Accept" ":"
#( media-range [ accept-params ] )
media-range = ( "*/*"
| ( type "/" "*")
| ( type "/" subtype )
) *( ";" parameter )

accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]

Символ звездочка "*" используется для того, чтобы группировать типы среды в группы с "*/*", указывающим на все типы, и "type/*", указывающим на все субтипы данного типа. Группа сред может включать в себя параметры типа среды, которые применимы. За каждой группой сред может следовать один или более параметров приема (accept-params), начинающихся с "q" параметра для указания фактора относительного качества. Первый "q" параметр (если таковой имеется) отделяет параметры группы сред от параметров приема. Факторы качества позволяют пользователю или агенту пользователя указать относительную степень предпочтения для данной группы сред, используя шкалу значений q от 0 до 1 (раздел 2.9). Значение по умолчанию соответствует q=1.

Замечание. Использование имени параметра "q" для разделения параметров типа среды от параметров расширения Accept связано с исторической практикой. Это мешает присвоения параметру типа среды имени "q". Пример Accept: audio/*; q=0.2, audio/basic.

Должно интерпретироваться, как "Я предпочитаю audio/basic, но шлите мне любые типы аудио, если это лучшее, что имеется после 80% понижения качества".
Если поле заголовка Accept отсутствует, тогда предполагается, что клиент воспринимает все типы среды. Если поле заголовка Accept присутствует и, если сервер не может послать отклик, который является приемлемым, согласно комбинированному значению поля Accept, тогда сервер должен послать отклик 406 (not acceptable). Более сложный пример.

Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c

Это будет интерпретироваться следующим образом: "text/html и text/x-c являются предпочтительными типами сред, но, если их нет, тогда следует слать объект text/x-dvi, если он отсутствует, следует присылать объект типа text/plain".

Группы сред могут быть заменены другими группами или некоторыми специальными типами среды. Если используется более одного типа среды для данного типа, предпочтение отдается наиболее специфичному типу. Например,

Accept: text/*, text/html, text/html;level=1, */*
имеет следующие предпочтения:
1) text/html;level=1
2) text/html
3) text/*
4) */*

Фактор качества типа среды, ассоциированный с данным типом определен путем нахождения группы сред с наивысшим предпочтением, который подходит для данного типа. Например,

Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5

в результате будут установлены следующие величины:

text/html;level=1 = 1
text/html = 0.7
text/plain = 0.3
image/jpeg = 0.5
text/html;level=2 = 0.4
text/html;level=3 ; = 0.7




Замечание. Агент пользователя может быть создан с набором значений качества по умолчанию для определенных групп среды. Однако, если только агент пользователя не является закрытой системой, которая не может взаимодействовать с другими агентами, этот набор по умолчанию должен быть конфигурируем пользователем.

13.2. Поле Accept-Charset

Поле заголовка запроса Accept-Charset может быть использовано для указания того, какой символьный набор приемлем для отклика. Это поле позволяет клиентам, способным распознавать более обширные или специальные наборы символов, сигнализировать об этой возможности серверу, который способен представлять документы в рамках этих символьных наборов.


Набор символов ISO-8859- 1 может считаться приемлемым для всех агентов пользователя.

Accept-Charset = "Accept-Charset" ":"
1#( charset [ ";" "q" "=" qvalue ] )

Значения символьных наборов описаны в разделе 2.4. Каждому символьному набору может быть поставлено в соответствие значение качества, которое характеризует степень предпочтения пользователя для данного набора. Значение по умолчанию q=1. Например Accept-Charset: ISO-8859-5, unicode-1-1;q=0.8. Если заголовок Accept-Charset отсутствует, по умолчанию это означает, что приемлем любой символьный набор. Если заголовок Accept-Charset присутствует, и, если сервер не может послать отклик, который приемлем с точки зрения заголовка Accept-Charset, тогда он должен послать сообщение об ошибке со статусным кодом 406 (not acceptable), хотя допускается посылка и отклика "unacceptable".

13.3. Поле Accept-Encoding

Поле заголовка запроса Accept-Encoding сходно с полем Accept, но регламентирует кодировку содержимого (раздел 13.12), которая приемлема в отклике.

Accept-Encoding = "Accept-Encoding" ":"
#( content-coding )

Ниже приведен пример его использования Accept-Encoding: compress, gzip

Если заголовок Accept-Encoding в запросе отсутствует, сервер может предполагать, что клиент воспримет любую кодировку информации. Если заголовок Accept-Encoding присутствует и, если сервер не может послать отклик, приемлемый согласно этому заголовку, тогда серверу следует послать сообщение об ошибке со статусным кодом 406 (Not Acceptable). Пустое поле Accept-Encoding указывает на то, что не приемлемо никакое кодирование.

13.4. Поле Accept-Language

Поле заголовка запроса Accept-Language сходно с полем Accept, но регламентирует набор естественных языков, которые предпочтительны в отклике на запрос.
Accept-Language = "Accept-Language" ":"
1#( language-range [ ";" "q" "=" qvalue ] )
language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )




Каждому набору языков может быть поставлено в соответствие значение качества, которое представляет собой оценку предпочтений пользователя для языков, специфицированных в диапазоне. По умолчанию значение качества "q=1". Например,

Accept-Language: da, en-gb;q=0.8, en;q=0.7

будет означать: "Я предпочитаю датский, но восприму британский английский и другие типы английского". Список языков согласуется с языковой меткой, если он в точности равен метке или, если он в точности равен префиксу метки, такому как первый символ метки, за которым следует символ "-". Специальный список "*", если он присутствует в поле Accept-Language, согласуется с любой меткой.

Замечание. Это использование префикса не предполагает, что языковые метки присвоены языкам таким образом, что, если пользователь понимает язык с определенной меткой, то он поймет все языки, имеющие метки с одним и тем же префиксом. Правило префикса просто позволяет использовать префиксные метки для случаев, когда это справедливо.

Фактор качества, присваиваемый языковой метке с помощью поля Accept-Language, равен значению качества самого длинного списка языков в поле. Если в поле отсутствует список языков, фактору качества присваивается значение нуль. Если в запросе отсутствует заголовок Accept-Language, серверу следует предполагать, что все языки приемлемы в равной мере. Если заголовок Accept-Language имеется, тогда все языки, которым присвоен фактор качества больше нуля, приемлемы.

Посылка заголовка Accept-Language с полным списком языковых предпочтений пользователя в каждом запросе может восприниматься как нарушение принципов конфиденциальности. Обсуждение этой проблемы смотри в разделе 14.7.

Замечание. Так как степень интеллигентности в высшей степени индивидуальна, рекомендуется, чтобы приложения клиента делали выбор языковых предпочтений доступным для пользователя. Если выбор не сделан доступным, тогда поле заголовка Accept-Language не должно присутствовать в запросе.

13.5.


Поле Accept-Ranges


Поле заголовка отклика Accept- Ranges позволяет серверу указать доступность широкодиапазонных запросов к ресурсу:

Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges
acceptable-ranges = 1#range-unit | "none"

Исходные серверы, которые воспринимают байт-диапазонные запросы, могут послать

Accept-Ranges: bytes

но делать это необязательно. Клиенты могут выдавать байт-диапазонные запросы, не получив этот заголовок отклика для запрашиваемого ресурса. Серверы, которые не могут работать с какими-либо диапазонными запросами, могут послать

Accept-Ranges: none,

чтобы посоветовать клиенту, не пытаться посылать такие запросы.

13.6. Поле Age

Поле заголовка отклика Age передает оценку отправителем времени с момента формирования отклика исходным сервером (или перепроверки его пригодности). Кэшированный отклик является свежим, если его возраст не превышает его времени жизни. Значения Age вычисляются согласно рекомендациям представленным разделе 12.2.3.
Age = "Age" ":" age-value
age-value = delta-seconds


Значения Age являются неотрицательным десятичным целым числом, характеризующим возраст записи в секундах.

Если кэш получает величину больше, чем наибольшее положительное число, которое он может себе представить или, если вычисление возраста вызвало переполнение, он должен передать заголовок Age со значением 2147483648 (231). Кэши HTTP/1.1 должны посылать заголовки Age в каждом отклике. Кэшам следует использовать арифметический тип чисел не менее 31 бита.

13.7. Поле Allow

Поле заголовка объекта Allow перечисляет набор методов, поддерживаемых ресурсом, идентифицированным Request-URI. Целью этого поля является точное информирование получателя о рабочих методах данного ресурса. Поле заголовка Allow должно быть представлено в отклике 405 (Method Not Allowed).

Allow = "Allow" ":" 1#method

Пример использования:

Allow: GET, HEAD, PUT

Это поле не препятствует клиенту испытать другие методы.


Однако указания, данные в значение поля заголовка Allow, следует выполнять. Действительный набор методов определяется исходным сервером во время каждого запроса.

Поле заголовка Allow может быть прислано запросом PUT, чтобы рекомендовать методы, которые будут поддерживаться новым или модифицированным ресурсом. Серверу не обязательно поддерживает эти методы, но ему следует включить заголовок Allow в отклик, чтобы сообщить действительно поддерживаемые методы.

Прокси не должен модифицировать поле заголовка Allow, даже если он не понимает все специфицированные методы, так как агент пользователя может иметь другие средства связи с исходным сервером.

Поле заголовка Allow не указывают на то, что методы реализованы на уровне сервера. Серверы могут использовать поле заголовка отклика Public (раздел 13.35), чтобы описать, какие методы реализованы на сервере.

13.8. Авторизация

Агент пользователя, который хочет авторизовать себя на сервере может сделать это после получения отклика 401, включив в запрос поле заголовка Authorization. Значение поля Authorization состоит из идентификационной информации агента пользователя для области (realm) запрошенных ресурсов.

Authorization = "Authorization" ":" credentials

Авторизация доступа HTTP описана в разделе 10. Если запрос идентифицирован и область специфицирована, та же самая идентификационная информация может быть использована для других запросов в пределах данной области.

Когда кэш коллективного пользования (см. раздел 12.7) получает запрос, содержащий поле Authorization, он не должен присылать соответствующий отклик в качестве ответа на какой-либо другой запрос, если только не выполняется одно из следующих условий:


  1. Если отклик включает в себя директиву Cache-Control "proxy-revalidate", кэш может использовать этот отклик при последующих запросах, но прокси-кэш должен сначала перепроверить его пригодность с помощью исходного сервера, используя заголовки нового запроса для того, чтобы исходный сервер мог идентифицировать новый запрос.




  2. Если отклик содержит в себе директиву Cache-Control "must-revalidate", кэш может использовать этот отклик при ответах на последующие запросы, но все кэши должны сначала перепроверить пригодность откликов с помощью исходного сервера, используя заголовки нового запроса для того, чтобы сервер мог идентифицировать новый запрос.


  3. Если отклик содержит директиву Cache-Control "public", то этот отклик может быть отослан в ответ на любой последующий запрос.


13.9. Поле Cache-Control

Поле общего заголовка Cache-Control используется для спецификации директив, которые должны исполняться всеми механизмами кэширования вдоль цепочки запрос/отклик. Директивы определяют поведение, которое, как предполагается, должно предотвратить нежелательную интерференцию откликов или запросов в кэше. Эти директивы обычно переписывают алгоритм кэширования, используемый по умолчанию. Директивы кэша являются однонаправленными, присутствие директивы в запросе не предполагает, что та же директива будет присутствовать и в отклике.

Заметьте, что кэши HTTP/1.0 могут не реализовывать управление (Cache-Control), а могут использовать только директиву Pragma: no-cache (см. раздел 13.32).

Директивы кэша должны пропускаться через приложения прокси или внешнего шлюза (gateway), вне зависимости от их значения для этого приложения, так как директивы могут быть применимы для всех получателей в цепочке запрос/отклик. Невозможно специфицировать директивы для отдельных кэшей.
Cache-Control = "Cache-Control" ":" 1#cache-directive
cache-directive = cache-request-directive
| cache-response-directive
cache-request-directive = "no-cash" ["=" <">1#field-name<">]
| "no-store"
| "max-age" "=" delta-seconds
| "max-stale" [ "=" delta-seconds ]
| "min-fresh" "=" delta-seconds
| "only-if-cached"
| cache-extension
cache-response-directive = "public"
| "private" [ "=" <"> 1#field-name <"> ]
| "no-cache" [ "=" <"> 1#field-name <"> ]
| "no-store"
| "no-transform"
| "must-revalidate"
| "max-age" "=" delta-seconds
| cache-extension;
cache-extension = token [ "=" ( token | quoted-string ) ]




Если директива появляется без какого-либо параметра 1#field-name, она воздействует на весь запрос или отклик. Когда такая директива приходит с параметром 1#field-name, она воздействует только на именованное поле или поля и не имеет никакого действия на остальную часть запроса или отклика. Этот механизм поддерживает расширяемость. Реализации будущих версий протокола HTTP могут использовать эти директивы для полей заголовка, неопределенных в HTTP/1.1.

Директивы управления кэшем могут быть разделены на следующие категории:


  • Ограничения на то, что можно кэшировать. Они налагаются только исходным сервером.


  • Ограничения на то, что можно записывать в память кэша. Они определяются исходным сервером или агентом пользователя.


  • Модификации базового механизма контроля годности записей. Они вносятся либо исходным сервером, либо агентом пользователя.


  • Управление процессом перепроверки годности записей и перезагрузкой осуществляется только агентом пользователя.


  • Управление преобразованием объектов.


  • Расширения системы кэширования.


13.9.1. Что допускает кэширование?

По умолчанию отклик допускает кэширование, если требования метода запроса, поля заголовка запроса и код статуса отклика указывают на то, что кэширование не запрещено. Раздел 12.4 обобщает эти рекомендации для кэширования. Следующие Cache-Control директивы отклика позволяют исходному серверу переписать стандартные требования по кэшируемости:

public

Указывает, что отклик может кэшироваться любым кэшем, даже если он в норме не кэшируем или кэшируем только в кэшах индивидуального пользования. (См. также об авторизации в разделе 13.8.)

private

Указывает, что весь или часть сообщения отклика предназначена для одного пользователя и не должна быть записана кэшем коллективного пользования. Это позволяет исходному серверу заявить о том, что специфицированные части отклика предназначены только для одного пользователя, и он не может отсылаться в ответ на запросы других пользователей. Частный кэш может кэшировать такие отклики.



Замечание. Это использование слова частный (private) определяет только возможность кэширования и не гарантирует конфиденциальности для содержимого сообщения.

no-cache

Указывает, весь или фрагмент сообщения-отклика не должны кэшироваться, где бы то ни было. Это позволяет исходному серверу предотвратить кэширование даже для кэшей, сконфигурированных для рассылки устаревших откликов.

Замечание. Большинство кэшей HTTP/1.0 не распознают и не исполняют эту директиву.

13.9.2. Что может быть записано в память кэша?

Целью директивы no-store (не запоминать) является предотвращение ненамеренного распространения или записи конфиденциальной информации (например, на backup ленты). Директива no-store применяется для всего сообщения и может быть послана как в отклике, так и в запросе. При посылке в запросе кэш не должен запоминать какую-либо часть этого запроса или присланного в ответ отклика. При посылке в отклике, кэш не должен запоминать какую-либо часть отклика или запроса, его вызвавшего. Эта директива действует как для индивидуальных кэшей, так и кэшей коллективного пользования. "Не должно запоминаться" в данном контексте означает, что кэш не должен заносить отклик в долговременную память и должен сделать все от него зависящее для того, чтобы удалить эту информацию из временной памяти после переадресации этих данных.

Даже когда эта директива ассоциирована с откликом, пользователи могут непосредственно запомнить такой отклик вне системы кэширования (например, с помощью диалога "Save As"). Буферы предыстории могут запоминать такие отклики как часть своей нормальной работы.

Цель этой директивы обеспечение выполнения определенных требований пользователей и разработчиков, кто связан с проблемами случайного раскрытия информации за счет непредвиденного доступа к структуре данных кэша. При использовании этой директивы можно в некоторых случаях улучшить конфиденциальность, но следует учитывать, что не существует какого-либо надежного механизма для обеспечения конфиденциальности.


В частности, некоторые кэши могут не распознавать или не выполнять эту директиву, а коммуникационные сети могут прослушиваться.

13.9.3. Модификации базового механизма контроля времени жизни

Время пригодности объекта (entity expiration time) может быть специфицировано исходным сервером с помощью заголовка Expires (см. раздел 13.21). Другой возможностью является применение директивы max-age в отклике.

Если отклик включает в себя как заголовок Expires, так и директиву max-age, более высокий приоритет имеет директива max-age, даже если заголовок Expires накладывает более жесткие ограничения. Это правило позволяет исходному серверу обеспечить для заданного отклика большее время жизни в случае объектов кэша HTTP/1.1 (или более поздней версии), чем в HTTP/1.0. Это может быть полезным, если кэш HTTP/1.0 некорректно вычисляет возраст объекта или его время пригодности, например, из-за не синхронности часов.

Замечание. Большинство старых кэшей, несовместимых с данной спецификацией, не поддерживают применение директив управления кэшем. Исходный сервер, желающий применить директиву управления кэшем, которая ограничивает, но не запрещает кэширование в системах, следующих регламентациям HTTP/1.1, может использовать то, что директива max-age переписывает значение, определенное Expires.

Другие директивы позволяют агенту пользователя модифицировать механизм контроля времени жизни объектов. Эти директивы могут быть специфицированы в запросе max-age.

Этот запрос указывает, что клиент желает воспринять отклик, чей возраст не больше времени, заданного в секундах. Если только не включена также директива max-stale, клиент не воспримет устаревший отклик.

Запрос min-fresh указывает, что клиент желает воспринять отклик, чье время жизни не меньше, чем его текущий возраст плюс заданное время в секундах. То есть, клиент хочет получит отклик, который будет еще свежим, по крайней мере, заданное число секунд.

Запрос max-stale указывает, что клиент желает воспринять отклик, время жизни которого истекло.


Если max- stale присвоено конкретное значение, тогда клиент хочет получить отклик, время жизни которого не ранее, чем заданное число секунд тому назад. Если значения max-stale в директиве не указано, тогда клиент готов воспринять отклики любого возраста.

Если кэш присылает устаревший отклик, из-за наличия в запросе директивы max-stale, либо потому, что кэш сконфигурирован таким образом, что переписывает время жизни откликов, кэш должен присоединить заголовок предупреждения к отклику, используя Warning 10 (Response is stale - отклик устарел).

13.9.4. Управление перепроверкой пригодности и перезагрузкой

Иногда агент пользователя может потребовать, чтобы кэш перепроверил пригодность своих записей с помощью исходного сервера (а не соседнего кэша по пути к исходному серверу), или перезагрузил свой кэш из исходного сервера. Может потребоваться перепроверка End-to-end, если и кэш и исходный сервер имеют завышенные оценки времени жизни кэшированных откликов. Перезагрузка End-to-end может потребоваться, если запись в кэше оказалась по какой-то причине поврежденной.

Перепроверка типа End-to-end может быть запрошена в случае, когда клиент не имеет своей локальной копии, этот вариант мы называем "не специфицированная перепроверка end-to-end", или когда клиент имеет локальную копию, такой вариант называется "специфической перепроверкой end-to-end."

Клиент может потребовать три вида действий, используя в запросе директивы управления кэшем:

End-to-end reload

Запрос включает в себя директиву управления кэшем "no-cache" или, для совместимости с клиентами HTTP/1.0, "Pragma: no-cache". В запросе с директивой no-cache может не быть никаких имен полей. Сервер не должен использовать кэшированную копию при ответе на этот запрос.

Specific end-to-end revalidation

Запрос включает в себя директиву управления кэшем "max-age=0", которая вынуждает каждый кэш вдоль пути к исходному серверу сверить свою собственную запись, если она имеются, с записью следующего кэша или сервера.


Исходный запрос включает в себя требования перепроверки для текущего значениея валидатора клиента.

Unspecified end-to-end revalidation

Запрос включает в себя директиву управления кэшем "max-age=0", которая вынуждает каждый кэш вдоль пути к исходному серверу сверить свою собственную запись, с записью следующего кэша или сервера. Исходный запрос не включает в себя требований перепроверки. Первый кэш по пути (если таковой имеется), который содержит запись данного ресурса, подключает условия перепроверки со своим текущим валидатором.

Когда промежуточный кэш вынуждается с помощью директивы max-age=0 перепроверить свои записи, присланный клиентом валидатор может отличаться от того, что записан в данный момент в кэше. В этом случае кэш может воспользоваться в своем запросе любой из валидаторов, не нарушая семантической прозрачности.

Однако выбор валидатора может влиять на результат. Наилучшим подходом для промежуточного кэша является использование в запросе своего собственного валидатора. Если сервер присылает отклик 304 (Not Modified), тогда кэш должен отправить свою уже проверенную копию клиенту со статусным кодом 200 (OK). Если сервер присылает отклик с новым объектом и валидатором кэша, промежуточный кэш должен сверить, тем не менее, полученный валидатор с тем, что прислал клиент, используя функцию сильного сравнения. Если валидатор клиента равен присланному сервером, тогда промежуточный кэш просто возвращает код 304 (Not Modified). В противном случае он присылает новый объект со статусным кодом 200 (OK).

Если запрос включает в себя директиву no-cache, в нем не должно быть min-fresh, max-stale или max-age.

В некоторых случаях, таких как периоды исключительно плохой работы сети, клиент может захотеть возвращать только те отклики, которые в данный момент находятся в памяти, и не перезагружать или перепроверять записи из исходного сервера. Для того чтобы сделать это, клиент может включить в запрос директиву only-if-cached. При получении такой директивы кэшу следует либо реагировать, используя кэшированную запись, которая соответствует остальным требованиям запроса, либо откликаться статусным кодом 504 (Gateway Timeout).


Однако если группа кэшей работает как унифицированная система с хорошей внутренней коннективностью, тогда такой запрос может быть переадресован в пределах группы кэшей

Так как кэш может быть сконфигурирован так, чтобы игнорировать времена жизни, заданные сервером, а запрос клиента может содержать директиву max-stale, протокол включает в себя механизм, который позволяет серверу требовать перепроверки записей в кэше для любого последующего применения. Когда в отклике, полученном кэшем, содержится директива must-revalidate, этот кэш не должен использовать эту запись для откликов на последующие запросы без сверки ее на исходном сервере. Таким образом, кэш должен выполнить перепроверку end-to-end каждый раз, если согласно значениям Expires или max-age, кэшированный отклик является устаревшим.

Директива must-revalidate необходима для поддержания надежной работы для определенных функций протокола. При любых обстоятельствах HTTP/1.1 кэш должен выполнять директиву must-revalidate. В частности, если кэш по какой-либо причине не имеет доступа к исходному серверу, он должен генерировать отклик 504 (Gateway Timeout).

Серверы должны посылать директиву must-revalidate, тогда и только тогда, когда неудача запроса перепроверки объекта может вызвать нарушение работы системы, например, не выполнение финансовой операции без оповещения об этом. Получатели не должны осуществлять любые автоматические действия, которые нарушают эту директиву, и не должны посылать непригодную копию объекта, если перепроверка не удалась.

Хотя это и не рекомендуется, агенты пользователя, работающие в условиях очень плохой коннективности, могут нарушать эту директиву, но, если это происходит, пользователь должен быть предупрежден в обязательном порядке, что присланный отклик возможно является устаревшим. Предупреждение должно посылаться в случае каждого непроверенного доступа, при этом следует требовать подтверждения от пользователя.

Директива proxy-revalidate имеет то же значение, что и must-revalidate, за исключением того, что она не применима для индивидуальных кэшей агентов пользователя.


Она может использоваться в отклике на подтвержденный запрос, чтобы разрешить кэшу пользователя запомнить и позднее прислать отклик без перепроверки (так как он был уже подтвержден однажды этим пользователем), в то же время прокси должен требовать перепроверки всякий раз при обслуживании разных пользователей (для того чтобы быть уверенным, что каждый пользователь был авторизован). Заметьте, что такие авторизованные отклики нуждаются также в директиве управления кэшем public для того, чтобы разрешить их кэширование.

13.9.5. Директива No-Transform

Разработчики промежуточных кэшей (прокси) выяснили, что полезно преобразовать тип среды для тел определенных объектов. Прокси может, например, преобразовать форматы изображения для того, чтобы сэкономить место в памяти кэша или чтобы уменьшить информационный поток в тихоходном канале. HTTP должен датировать такие преобразования, выполняемые без оповещения.

Серьезные операционные проблемы происходят, однако, когда такие преобразования производятся над телами объектов, предназначенных для определенного сорта приложений. Например, использующих медицинские изображения, предназначенные для анализа научных данных, а также тех, которые применяют авторизацию end-to-end, или требуют побитной совместимости с оригиналом.

Следовательно, если отклик содержит директиву no-transform, промежуточный кэш или прокси не должны изменять те заголовки, которые перечислены в разделе 12.5.2, так как они могут содержать директиву no-transform. Это предполагает, что кэш или прокси не должны изменять любую часть тела объекта, который имеет такие заголовки.

13.9.6. Расширения управления кэшем

Поле заголовка Cache-Control может быть расширено за счет использования одной или более лексем расширения, каждой из которых может быть присвоено определенное значение. Информационные расширения (те которые не требуют изменений в работе кэша) могут быть добавлены без изменения семантики других директив. Поведенческие расширения спроектированы для того, чтобы выполнять функции модификаторов существующих директив управления кэшем.


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

Этот механизм расширений зависит от того, выполняет ли кэш все директивы управления, определенные для базовой версии HTTP. Предполагается, что кэш реализует определенные расширения и игнорирует все директивы, которые не может распознать.

Например, рассмотрим гипотетическую, новую директиву, названную "community", которая действует как модификатор директивы "private". Мы определяем эту новую директиву так, что в дополнение к стандартным возможностям индивидуальных кэшей, кэши, которые обслуживают группу (community), могут кэшировать их отклики. Исходный сервер, желающий позволить группе "UCI" использовать частные отклики на их общем кэше, может решить эту проблему, включив директиву управления кэшем: private, community="UCI".

Кэш, получив это поле заголовка, будет действовать корректно, если даже не понимает расширение "community", так как он видит и понимает директиву "private" и, таким образом, по умолчанию обеспечит безопасное функционирование.

Не распознанная директива управления должна игнорироваться. Предполагается, что любая директива, в том числе и не узнанная кэшем HTTP/1.1, имеет по умолчанию стандартную директиву-подмену, которая обеспечивает определенный уровень функциональности, когда директива-расширение не распознается.

13.10. Соединение

Поле общего заголовка Connection позволяет отправителю специфицировать опции, которые желательны для конкретного соединения. Заголовок Connection имеет следующую грамматику:

Connection-header = "Connection" ":" 1#(connection-token)
connection-token = token

Прокси-серверы HTTP/1.1 должны выполнить разбор поля заголовка Connection, прежде чем выполнить переадресацию, и для каждой лексемы соединения в этом поле убрать любые поля заголовка в сообщении с именами, совпадающими с этими лексемами.


Опции Connection отмечаются присутствием лексем соединения в поле заголовка Connection, а не какими-либо дополнительными полями заголовка, так как дополнительное поле заголовка может быть не послано, если нет параметров, ассоциированных с данной опцией соединения. HTTP/1.1 определяет опцию "close" (закрыть) для отправителя, чтобы сигнализировать о том, что соединение будет закрыто после завершения передачи отклика. Например, наличие

Connection: close

как в полях запроса, так и в полях отклика указывает на то, что соединение не следует рассматривать как "постоянное" (раздел 7.1) после завершения передачи данного запроса/отклика.

Приложения HTTP/1.1, которые не поддерживают постоянные соединения, должны содержать опцию соединения "close" в каждом сообщении.

13.11. Content-Base

Поле заголовка объекта Content-Base может быть использовано для спецификации базового URI, которое позволяет работать с относительными URL в пределах объекта. Это поле заголовка описано как Base в документе RFC 1808, который, как ожидается, будет пересмотрен.

Content-Base = "Content-Base" ":" absoluteURI

Если поле Content-Base отсутствует, базовый URI объекта определяется его Content-Location (если это Content-Location URI является абсолютным) или URI используется для инициации запроса. Заметьте, однако, что базовый URI содержимого в пределах тела объекта может быть переопределен.

13.12. Кодирование содержимого

Поле заголовка объекта Content-Encoding используется в качестве модификатора типа среды. Если это поле присутствует, его значение указывает, что тело объекта закодировано, и какой механизм декодирования следует применить, чтобы получить массив данных, ориентированный на тип среды, указанный в поле Content-Type. Поле Content-Encoding первоначально предназначалось для того чтобы архивировать документ без потери его идентичности с учетом типа среды, на которую он ориентирован.

Content-Encoding = "Content-Encoding" ":" 1#content-coding



Кодировки содержимого определены в разделе 2.5. Пример его использования приведен ниже

Content-Encoding: gzip

Content-Encoding ( кодирование содержимого) является характеристикой объекта, задаваемой Request-URI. Обычно тело объекта заносится в память в закодированном виде и декодируется перед отображением или другим аналогичным использованием.

Если было применено множественное кодирование объекта, кодирование содержимого должно быть перечислено в том порядке, в котором оно было выполнено.

13.13. Язык содержимого

Поле заголовка объекта Content-Language описывает естественный язык(и) потенциальных читателей вложенного объекта. Заметьте, что это может быть совсем не эквивалентно всем языкам, использованным в теле объекта.

Content-Language = "Content-Language" ":" 1#language-tag

Языковые метки определены в разделе 2.10. Первоначальной целью поля Content-Language является предоставление пользователю возможности дифференцировать объекты согласно языковым предпочтениям. Таким образом, если содержимое тела предназначено только для аудитории, говорящей на датском языке, подходящим содержимым поля Content-Language может быть

Content-Language: da

Если поле Content-Language не задано, по умолчанию считается, что содержимое ориентировано на любую аудиторию. Это может значить, что отправитель не выделяет какой-либо естественный язык конкретно, или что отправитель не знает, какой язык предпочесть.

Список языков может быть предложен для текста, который предназначен для многоязыковой аудитории. Например, перевод "Treaty of Waitangi," представленный одновременно в оригинальной версии на маори и на английском, может быть вызван с помощью

Content-Language: mi, en

Однако только то, что в поле объекта перечислено несколько языков не означает, что объект предназначен для многоязыковой аудитории. Примером может быть языковый курс для начинающих, такой как "A First Lesson in Latin," который предназначен для англо-говорящей аудитории. В этом случае поле Content-Language должно включать только "en".



Поле Content-Language может быть применено к любому типу среды - оно не ограничено только текстовыми документами.

13.14. Длина содержимого

Содержимое поля заголовка объекта Content-Length указывает длину тела сообщения в октетах (десятичное число), посылаемое получателю, или в случае метода HEAD, размер тела объекта, который мог бы быть послан при запросе GET.

Content-Length = "Content-Length" ":" 1*DIGIT

Например

Content-Length: 3495

Приложениям следует использовать это поле для указания размера сообщения, которое должно быть послано вне зависимости от типа среды. Получатель должен иметь возможность надежно определить положение конца запроса HTTP/1.1, содержащего тело объекта, например, запрос использует Transfer-Encoding chunked или multipart body.

Любое значение Content-Length больше или равное нулю допустимо. Раздел 3.4 описывает то, как определить длину тела сообщения, если параметр Content-Length не задан.

Замечание. Значение этого поля заметно отличается от соответствующего определения в MIME, где оно является опционным, используемым в типе содержимого "message/external-body". В HTTP его следует посылать всякий раз, когда длина сообщения должна быть известна до начала пересылки.

13.15. Поле Content-Location

Поле заголовка объекта Content-Location может быть использовано для определения положения ресурса для объекта, вложенного в сообщение. В случае, когда ресурс содержит много объектов, и эти объекты в действительности имеют разные положения, по которым может быть осуществлен доступ, сервер должен предоставить поле Content-Location для конкретного варианта, который должен быть прислан. Кроме того сервер должен предоставить Content-Location для ресурса, соответствующего объекту отклика.

Content-Location = "Content-Location" ":"
( absoluteURI | relativeURI )

Если поле заголовка Content-Base отсутствует, значение Content-Location определяет также базовый URL для объекта (см. раздел 13.11).

Значение Content-Location не является заменой для исходного запрашиваемого URI, это лишь объявление положения ресурса, соответствующего данному конкретному объекту в момент запроса.


Будущие запросы могут использовать Content- Location URI, если нужно идентифицировать источник конкретного объекта.

Кэш не может предполагать, что объект с полем Content-Location, отличающимся от URI, который использовался для его получения, может использоваться для откликов на последующие запросы к этому Content-Location URI. Однако Content-Location может использоваться для того, чтобы отличить объекты, полученные из одного общего, как это описано в разделе 12.6.

Если Content-Location является относительным URI, URI интерпретируется с учетом значения Content-Base URI, присланного в отклике. Если значения Content-Base не предоставлено, относительный URI интерпретируется по отношению к Request-URI.

13.16. Content-MD5

Поле заголовка объекта Content-MD5, как это определено в RFC 1864 [23], является MD5-дайджестом тела объекта для целей обеспечения проверки end-to-end целостности сообщения MIC (message integrity check). Замечание. MIC привлекательна для регистрации случайных модификаций тела объекта при транспортировке, но не является гарантией против преднамеренных действий.)
Content MD5 = "Content-MD5" ":" md5-digest
md5digest =


Поле заголовка Content-MD5 может генерироваться исходным сервером с целью проверки целостности тел объектов. Только исходные серверы могут генерировать поле заголовка Content-MD5. Прокси и внешние шлюзы его генерировать не должны, так как это сделает невозможными проверку целостности end-to-end. Любой получатель тела объекта, включая внешние шлюзы и прокси, могут проверять то, что значение дайджеста в этом поле заголовка согласуется с полученным телом объекта.

Дайджест MD5 вычисляется на основе содержимого тела сообщения, с учетом любых кодировок содержимого, но исключая любые транспортные кодировки (Transfer-Encoding), которые могли быть использованы. Если сообщение получено в закодированном виде с использованием Transfer-Encoding, это кодирование должно быть удалено перед проверкой значения Content-MD5 для полученного объекта.



Это означает, что дайджест вычисляется для октетов тела объекта в том порядке, в каком они будут пересланы, если не используется транспортное кодирование.

HTTP расширяет RFC 1864 с тем, чтобы разрешить вычисление дайджеста для MIME-комбинации типов среды (например, multipart/* и message/rfc822), но это никак не влияет на способ вычисления дайджеста, описанного выше.

Замечание. Существует несколько следствий этого. Тело объекта для комбинированных типов может содержать много составных частей, каждая со своими собственными MIME и HTTP заголовками (включая заголовки Content-MD5, Content-Transfer-Encoding и Content-Encoding). Если часть тела имеет заголовок Content-Transfer-Encoding или Content-Encoding, предполагается, что содержимое этой части закодировано и она включается в дайджест Content-MD5 как есть. Поле заголовка Transfer-Encoding не применимо для частей тела объекта.

Замечание. Так как определение Content-MD5 является в точности тем же для HTTP и MIME (RFC 1864), существует несколько вариантов, в которых применение Content-MD5 к телам объектов HTTP отличается от случая MIME. Один вариант связан с тем, что HTTP, в отличие от MIME, не использует Content-Transfer-Encoding, а использует Transfer-Encoding и Content-Encoding. Другой - вызван тем, что HTTP чаще, чем MIME, использует двоичный тип содержимого. И, наконец, HTTP позволяет передачу текстовой информации с любым типом разрыва строк, а не только с каноническим CRLF. Преобразование всех разрывов строк к виду CRLF не должно делаться до вычисления или проверки дайджеста: тип оформления разрыва строк при расчете дайджеста должен быть сохранен.

13.17. Отрывок содержимого

Заголовок объекта Content-Range посылается с частью тела объекта и служит для определения того, где в теле объекта должен размещаться данный фрагмент. Он также указывает полный размер тела объекта. Когда сервер присылает клиенту частичный отклик, он должен описать как длину фрагмента, так и полный размер тела объекта.
Content-Range = "Content-Range" ":" content-range-spec
Content-range-spec = byte-content-range-spec
byte-content-range-spec = bytes-unit SP first-byte-pos "-"




last-byte-pos "/" entity-length

entity-length = 1*DIGIT


В отличие от значений спецификаторов байтовых диапазонов (byte-ranges-specifier), byte-content-range-spec может специфицировать только один интервал и должен содержать абсолютные положения, как первого, так и последнего байтов.

Некорректной считается спецификация 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: bytes 0-499/1234


  • The second 500 bytes: bytes 500-999/1234


  • All except for the first 500 bytes: bytes 500-1233/1234


  • The last 500 bytes: bytes 734-1233/1234


Когда сообщение HTTP включает в себя содержимое одного фрагмента (например, отклик на запрос одного фрагмента, или на запрос набора фрагментов, которые перекрываются без зазоров), это содержимое передается с заголовком Content-Range, а заголовок Content-Length несет в себе число действительно переданных байт. Например,

HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

Когда сообщение HTTP несет в себе содержимое нескольких фрагментов (например, отклик на запрос получения нескольких, не перекрывающихся фрагментов), они передаются как многофрагментное MIME-сообщение. Многофрагментный тип данных MIME используемый для этой цели, определен в этой спецификации как "multipart/byteranges". (Смотри приложение 16.2).

Клиент, который не может декодировать сообщение MIME multipart/byteranges, не должен запрашивать несколько байт-фрагментов в одном запросе.

Когда клиент запрашивает несколько фрагментов байт в одном запросе, серверу следует присылать их в порядке перечисления.



Если сервер игнорирует спецификацию byte-range-spec, из- за того, что она некорректна, сервер должен воспринимать запрос так, как если бы некорректного заголовка Range не существовало вовсе. (В норме это означает посылку отклика с кодом 200, содержащего весь объект). Причиной этого является то, что клиент может прислать такой некорректный запрос, только когда объект меньше чем объект, полученный по предыдущему запросу.

13.18. Тип содержимого

Поле заголовка объекта Content-Type указывает тип среды тела объекта, посланного получателю, или, в случае метода HEAD, тип среды, который был бы применен при методе GET.

Content-Type = "Content-Type" ":" media-type

Типы среды определены в разделе 2.7. Примером поля может служить

Content-Type: text/html; charset=ISO-8859-4

Дальнейшее обсуждение методов идентификации типа среды объекта приведено в разделе 6.2.1.

13.19. Дата

Поле общего заголовка Date представляет дату и время формирования сообщения, имеет ту же семантику, что и orig-date в RFC 822. Значение поля равно HTTP-date, как это описано в разделе 2.3.1.

Date = "Date" ":" HTTP-date

Пример

Date: Tue, 15 Nov 1994 08:12:31 GMT

Если сообщение получено через непосредственное соединение с агентом пользователя (в случае запросов) или исходным сервером (в случае откликов), дата может считаться текущей датой конца приема. Однако так как дата по определению является важной при оценке характеристик кэшированных откликов, исходный сервер должен включать поле заголовка Date в каждый отклик. Клиентам следует включать поле заголовка Date в сообщения, которые несут тело объекта запросов PUT и POST, но даже здесь это является опционным. Полученному сообщению, которое не имеет поля заголовка Date, следует присвоить дату. Это может сделать один из получателей, если сообщение будет кэшировано им, или внешним шлюзом.

Теоретически дата должна представлять момент времени сразу после генерации объекта. На практике поле даты может быть сформировано в любое время в процессе генерации сообщения.



Формат поля Date представляет собой абсолютную дату и время так, как это определено для даты HTTP в разделе 2.3. Оно должно быть послано в формате, описанном в документе RFC-1123 [8].

13.20. Поле ETag

Поле заголовка объекта ETag определяет метку объекта. Заголовки с метками объектов описаны в разделах 13.20, 13.25, 13.26 и 13.43. Метка объекта может использоваться для сравнения с другими объектами того же самого ресурса (см. раздел 12.8.2).

ETag = "ETag" ":" entity-tag
Примеры:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""

13.21. Поле Expires

Поле заголовка объекта Expires содержит дату/время с момента, когда отклик может считаться устаревшим. Устаревшая запись в кэше в норме не должна посылаться кэшем (а также прокси кэшем и кэшем агента пользователя), если только она не будет сначала перепроверена с помощью исходного сервера (или с помощью промежуточного кэша, который содержит свежую копию объекта). Дальнейшее обсуждение модели контроля пригодности записей содержится в разделе 12.2. Присутствие поля Expires не предполагает, что исходный ресурс изменит или удалит объект по истечении указанного времени.

Формат абсолютной даты и времени описан в разделе 2.3. Он должен следовать рекомендациям документа RFC1123:

Expires = "Expires" ":" HTTP-date

Примером реализации формата даты может служить

Expires: Thu, 01 Dec 1994 16:00:00 GMT

Замечание. Если отклик содержит поле Cache-Control с директивой max-age, то эта директива переписывает значение поля Expires.

Клиенты HTTP/1.1 и кэши должны рассматривать некорректные форматы даты, в особенности те, что содержат нули, как относящиеся к прошлому (то есть, как "уже истекшие").

Для того, чтобы пометить отклик, как "уже с истекшим сроком", исходный сервер должен использовать дату Expires, которая равна значению заголовка Date. (Правила вычисления времени истечения пригодности записи смотри в разделе 12.2.4.)

Для того, чтобы пометить отклик как "всегда пригодный", исходный сервер должен использовать дату Expires приблизительно на один год позже момента посылки отклика.


Серверы HTTP/1. 1 не должны посылать отклики с датами в поле Expires, которые устанавливают время жизни более одного года.

Присутствие поля заголовка Expires со значением даты, относящейся к будущему, означает, что они могут быть занесены в кэш, если только не указано обратного в поле заголовка Cache-Control (раздел 13.9).

13.22. Поле From

Поле заголовка запроса From (если присутствует) должно содержать интернетовский e-mail адрес пользователя. Адрес должен иметь формат, описанный в документе RFC-822 (и дополненный в RFC-1123):

From = "From" ":" mailbox

Пример:

From: webmaster@w3.org

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

Интернетовский e-mail адрес в этом поле может не совпадать с Интернет-адресом ЭВМ, пославшей запрос. Например, когда запрос прошел через прокси, следует использовать адрес первичного отправителя.

Замечание. Клиенту не следует посылать поле заголовка From без одобрения пользователя, так как это может вызвать конфликт с интересами конфиденциальности пользователя или нарушить политику безопасности сети отправителя. Настоятельно рекомендуется, чтобы пользователь мог дезактивировать, активировать и модифицировать значение этого поля в любое время до запроса.

13.23. Поле Host

Поле заголовка запроса Host специфицирует ЭВМ в Интернет и номер порта запрашиваемого ресурса в виде, полученном из исходного URL, который выдал пользователь или который получен из указанного ресурса (в общем случае из HTTP URL, как это описано в разделе 2.2.2). Значение поля Host должно определять положение в сети исходного сервера или шлюза, заданное исходным URL.


Это позволяет исходному серверу или шлюзу различать внутренние URL, такие как корневые "/" URL сервера для ЭВМ, которым поставлен в соответствие один IP адрес.

Host = "Host" ":" host [ ":" port ] ; Раздел 2.2.2

Имя "ЭВМ" без последующего номера порта предполагает значение порта по умолчанию для заданного вида сервиса (напр., "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.

О других требованиях относительно поля Host смотри раздел 4.2 и 16.5.1.

13.24. Поле If-Modified-Sinc

Поле заголовка запроса 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. Алгоритм определения этого включает в себя следующие шаги.


  1. Если запрос приводит к чему-то отличному от статусного отклика 200 (OK), или если переданная дата If-Modified-Since некорректна, отклик будет в точности тот же, что и для обычного GET.


    Дата раньше текущего времени сервера является некорректной.


  2. Если объект был модифицирован после даты If-Modified-Since, отклик будет в точности тем же, что и для обычного GET.


  3. Если объект не был модифицирован после корректно указанной даты If-Modified-Since, сервер должен прислать отклик 304 (Not Modified).


Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками.

Заметьте, что поле заголовка запроса Range модифицирует значение If-Modified-Since. Более детально эта проблема рассмотрена в разделе 13.36.

Заметьте, что время If-Modified-Since интерпретируются сервером, чьи часы могут быть не синхронизованы с часами клиента.

Если клиент использует произвольную дату в заголовке If-Modified-Since вместо даты взятой из заголовка Last-Modified для текущего запроса, тогда клиенту следует остерегаться того, что эта дата интерпретируется согласно представлениям сервера о временной шкале. Клиенту следует учитывать не синхронность часов и проблемы округления, связанные с различным кодированием времени клиентом и сервером. Это предполагает возможность быстрого изменения условий, когда документ изменяется между моментом первого запроса и датой If-Modified-Since последующего запроса, а также возможность трудностей, связанных с относительным сбоем часов, если дата If-Modified-Since получена по часам клиента (без поправки на показания часов сервера). Поправки для различных временных базисов клиента и сервера желательно делать с учетом времени задержки в сети.

13.25. Поле If-Match

Поле заголовка запроса If-Match используется с методом, для того чтобы сделать его условным. Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, является ли один из этих объектов текущим, включив список связанных с ним меток в поле заголовка If-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальными издержками. Она используется также в запросах актуализации с целью предотвращения непреднамеренной модификации не той версии ресурса что нужно.


Значение "*" соответствует любому текущему объекту ресурса.

If-Match = "If-Match" ":" ( "*" | 1#entity-tag )

Если какая-то метка объекта совпадает с меткой объекта, который прислан в отклике на аналогичный запрос GET (без заголовка If-Match), или если задана "*" и какой-то текущий объект существует для данного ресурса, тогда сервер может реализовать запрошенный метод, как если бы поля заголовка If-Match не существовало.

Сервер должен использовать функцию сильного сравнения (см. раздел 2.11) для сопоставления меток объекта в If-Match.

Если ни одна из меток не подходит, или если задана "*" и не существует никакого текущего объекта, сервер не должен реализовывать запрошенный метод, а должен прислать отклик 412 (Precondition Failed). Это поведение наиболее полезно, когда клиент хочет помешать актуализующему методу, такому как PUT, модифицировать ресурс, который изменился после последнего доступа к нему клиента.

Если запрос без поля заголовка If-Match выдает в результате нечто отличное от статуса 2xx, тогда заголовок If-Match должен игнорироваться.

"If-Match: *" означает, что метод должен быть реализован, если представление, выбранное исходным сервером (или кэшем, возможно с привлечением механизма Vary, см. раздел 13.43), существует, и не должен быть реализован, если выбранного представления не существует.

Запрос, предназначенный для актуализации ресурса (напр., PUT) может включать в себя поле заголовка If-Match, чтобы сигнализировать о том, что метод запроса не должен быть применен, если объект, соответствующий значению If-Match (одиночная метка объекта), не является более представлением этого ресурса. Это позволяет пользователям указывать, что они не хотят, чтобы запрос прошел успешно, если ресурс был изменен без их уведомления. Примеры:

If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *

13.26. Поле If-None-Match

Поле заголовка запроса If-None-Match используется для формирования условных методов.


Клиент, который имеет один или более объектов, полученных ранее из ресурса, может проверить, что ни один из этих объектов не является текущим, путем включения списка их ассоциированных меток в поле заголовка If-None-Match. Целью этой функции является эффективная актуализация кэшированной информации с минимальной избыточностью. Она также используется при актуализации запросов с тем, чтобы предотвратить непреднамеренную модификацию ресурса, о существовании которого не было известно.

Значение "*" соответствует любому текущему объекту ресурса.

If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )

Если какая-либо метка объекта соответствует метке объекта, который был прислан в отклике на аналогичный запрос GET (без заголовка If-None-Match) или если задана "*" и существует какой-то текущий объект данного ресурса, тогда сервер не должен реализовывать запрошенный метод. Вместо этого, если методом запроса был GET или HEAD, серверу следует реагировать откликом 304 (Not Modified), включая поля заголовков объекта, ориентированные на кэш (в частности ETag). Для всех других методах запроса сервер должен откликаться статусным кодом 412 (Precondition Failed).

По поводу правил того, как определять соответствие двух меток объектов смотри раздел 12.8.3. С запросами GET и HEAD должна использоваться только функция слабого сравнения.

Если не подходит ни одна из меток объекта или если задана "*" и не существует ни одного текущего объекта, сервер может выполнить запрошенный метод так, как если бы поля заголовка If-None-Match не существовало.

Если запрос без поля заголовка If-None-Match, даст результат отличный от статусного кода 2xx, тогда заголовок If-None-Match должен игнорироваться.

"If-None-Match: *" означает, что метод не должен реализовываться, если представление, выбранное исходным сервером (или кэшем, возможно использующим механизм Vary, см. раздел 13.43), существует, и должен быть реализован, если представления не существует.


Эта функция может быть полезной для предотвращения конкуренции между операциями 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: *

13.27. Заголовок If-Range

Если клиент имеет частичную копию объекта в своем кэше и хочет иметь полную свежую копию объекта, он может использовать заголовок запроса Range с условным GET (используя If-Unmodified-Since и/или If-Match.) Однако если условие не выполняется, из-за того, что объект был модифицирован, клиенту следует послать второй запрос, чтобы получить все текущее содержимое тела объекта.

Заголовок If-Range позволяет клиенту заблокировать второй запрос. По существу это означает, что "если объект не изменился, следует посылать мне часть, которой у меня нет, в противном случае пришлите мене всю новую версию объекта".

If-Range = "If-Range" ":" ( entity-tag | HTTP-date )

Если клиент не имеет метки объекта, но имеет дату Last-Modified, он может использовать эту дату в заголовке If-Range. Сервер может отличить корректную дату HTTP от любой формы метки объекта, рассмотрев не более двух символов. Заголовок If-Range следует использовать только совместно с заголовком Range, и его следует игнорировать, если запрос не содержит в себе этот заголовок, или если сервер не поддерживает операции с фрагментами.

Если метка объекта, представленная в заголовке If-Range, соответствует текущей метке, тогда сервер должен обеспечить специфицированный фрагмент объекта, используя отклик 206 (Partial content). Если метка объекта не подходит, сервер должен прислать полный объект со статусным кодом 200 (OK).

13.28. Поле If-Unmodified-Since

Поле заголовка запроса If-Unmodified-Since используется для того, чтобы формировать условные методы. Если запрошенный ресурс не был модифицирован с момента, указанного в поле, сервер должен произвести запрошенную операцию, так как если бы заголовок If-Unmodified-Since отсутствовал.



Если запрошенный объект был модифицирован после указанного времени, сервер не должен выполнять запрошенную операцию и должен прислать отклик 412 (Precondition Failed).

If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date

Примером поля может служить:

If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT

Если запрос завершается чем-то отличным от статусного кода 2xx (т.е., без заголовка If-Unmodified-Since), заголовок If-Unmodified-Since следует игнорировать. Если специфицированная дата некорректна, заголовок также игнорируется.

13.29. Поле Last-Modified

Поле заголовка объекта Last-Modified указывает на дату и время, при которых, по мнению исходного сервера, данный объект был модифицирован.

Last-Modified = "Last-Modified" ":" HTTP-date

Пример его использования

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

Точное значение этого заголовка зависит от реализации исходного сервера и природы ресурса. Для файлов, это может быть дата последней модификации файловой системы. Для объектов с динамическими встроенными частями это может время последней модификации одной из встроенных компонент. Для шлюзов баз данных это может быть метка последней модификации рекорда. Для виртуальных объектов это может быть время последнего изменения внутреннего состояния.

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

Исходный сервер должен получить значение Last-Modified объекта как можно ближе по времени к моменту генерации значения Date отклика. Это позволяет получателю выполнить точную оценку времени модификации объекта, в особенности, если объект был изменен буквально накануне формирования отклика.

Серверы HTTP/1.1 должны посылать поле Last-Modified всякий раз, когда это возможно.

13.30. Поле Location

Поле заголовка отклика Location используется для переадресации запроса на сервер, отличный от указанного в Request-URI, или для идентификации нового ресурса.


В случае отклика 201 (Created), поле Location указывает на новый ресурс, созданный в результате запроса. Для откликов 3xx поле Location должно указывать предпочтительные URL сервера для автоматической переадресации на ресурс. Значение поля включает одинарный абсолютный URL.

Location = "Location" ":" absoluteURI

Например

Location: http://www.w3.org/pub/WWW/People.html

Замечание. Поле заголовка Content-Location (раздел 13.15) отличается от поля Location в том, что Content-Location идентифицирует исходное положение объекта, заключенное в запросе. Следовательно, отклик может содержать поля заголовка как Location, так и Content-Location. Требования некоторых методов изложены также в разделе 12.10.

13.31. Поле Max-Forwards

Поле заголовка запроса Max-Forwards может использоваться с методом TRACE (раздел 13.31) ,чтобы ограничить число прокси или шлюзов, которые могут переадресовывать запрос. Это может быть полезным, когда клиент пытается отследить путь запроса в случае возникновения различных проблем.

Max-Forwards = "Max-Forwards" ":" 1*DIGIT

Значение Max-Forwards представляет собой целое десятичное число, которое указывает сколько еще раз запрос можно переадресовать.

Каждый прокси или шлюз получатель запроса TRACE, содержащего поле заголовка Max-Forwards, должен проверить и актуализовать его величину прежде, чем переадресовывать запрос. Если полученная величина равна нулю, получателю не следует переадресовывать запрос. Вместо этого, ему следует откликнуться как конечному получателю статусным кодом 200 (OK), содержащим полученное сообщение-запрос в качестве тела отклика (как это описано в разделе 8.8). Если полученное значение больше нуля, тогда переадресованное сообщение должно содержать актуализованное значение поля Max-Forwards (уменьшенное на единицу).

Поле заголовка Max-Forwards следует игнорировать для всех других методов определенных в данной спецификации и для всех расширений методов, для которых это не является частью определения метода.



13.32. Поле Pragma

Поле общего заголовка Pragma используется для включения специальных директив (зависящих от конкретной реализации), которые могут быть применены ко всем получателям вдоль цепочки запрос/отклик. Все директивы pragma специфицируют с точки зрения протокола опционное поведение. Однако некоторые системы могут требовать, чтобы поведение соответствовало директивам:
Pragma = "Pragma" ":" 1#pragma-directive
pragma-directive = "no-cache" | extension-pragma
extension-pragma = token [ "=" ( token | quoted-string ) ]


Когда в запросе присутствует директива no-cashe, приложение должно переадресовать запрос исходному серверу, даже если имеется кэшированная копия того, что запрошено. Директива pragma имеет ту же семантику, что и директива кэша no-cache (см. раздел 13.9) и определена здесь для обратной совместимости с HTTP/1.0. Клиентам следует включать в запрос оба заголовка, когда посылается запрос no-cache серверу, о котором неизвестно, совместим ли он с HTTP/1.1.

Нельзя специфицировать директиву pragma для какого-то отдельного получателя. Однако любая директива pragma неприемлемая для получателя должна им игнорироваться.

Клиенты HTTP/1.1 не должны посылать заголовок запроса Pragma. Кэши HTTP/1.1 должны воспринимать "Pragma: no-cache", как если бы клиент послал "Cache-Control: no-cache". Никаких новых директив Pragma в HTTP определено не будет.

13.33. Поле Proxy-Authenticate

Поле заголовка отклика Proxy-Authenticate должно быть включено в качестве части отклика 407 (Proxy Authentication Required). Значение поля состоит из вызова, который указывает схему идентификации, и параметров, применимых в прокси для данного Request-URI.

Proxy-Authenticate = "Proxy-Authenticate" ":" challenge

Процесс авторизованного доступа HTTP описан в разделе 10. В отличие от WWW-Authenticate, поле заголовка Proxy-Authenticate применимо только к текущему соединению и не может быть передано другим клиентам.


Однако, промежуточному прокси может быть нужно получить свои собственные авторизационные параметры с помощью запроса у ниже расположенного клиента, который при определенных обстоятельствах может проявить себя как прокси, переадресующий поле заголовка Proxy-Authenticate.

13.34. Поле Proxy-Authorization

Поле заголовка запроса Proxy-Authorization позволяет клиенту идентифицировать себя (или его пользователя) прокси, который требует авторизации. Значение поля Proxy-Authorization состоит из автризационных параметров, содержащих идентификационную информацию агента пользователя для прокси и/или области (realm) запрошенного ресурса.

Proxy-Authorization = "Proxy-Authorization" ":" credentials

Процесс авторизации доступа HTTP описан в разделе 10. В отличие от Authorization, поле заголовка Proxy-Authorization применимо только к следующему внешнему прокси, который требует авторизации с помощью поля Proxy-Authenticate. Когда работает несколько прокси, объединенных в цепочку, поле заголовка Proxy-Authorization используется первым внешним прокси, который предполагает получение авторизационных параметров. Прокси может передать эти параметры из запроса клиента следующему прокси, если существует механизм совместной авторизации при обслуживании данного запроса.

13.35. Поле Public

Поле заголовка отклика Public содержит список методов, поддерживаемых сервером. Задачей этого поля является информирование получателя о возможностях сервера в отношении необычных методов. Перечисленные методы могут быть, а могут и не быть применимыми к Request-URI. Поле заголовка Allow (раздел 13.7) служит для указания методов, разрешенных для данного URI.
Public = "Public" ":" 1#method


Пример использования:

Public: OPTIONS, MGET, MHEAD, GET, HEAD

Это поле заголовка применяется для серверов, непосредственно соединенных с клиентом, (т.е., ближайших соседей в цепи соединения). Если отклик проходит через прокси, последний должен либо удалить поле заголовка Public или заменить его полем, характеризующим его собственные возможности.



13.36. Фрагмент
13.36.1. Фрагменты байт


Так как все объекты HTTP в процессе передачи представляют собой последовательности байт, концепция фрагментов является существенной для любого объекта HTTP. Однако не все клиенты и серверы нуждаются в поддержке операций с фрагментами.

Спецификации байтовых фрагментов в HTTP относятся к последовательностям байт в теле объекта не обязательно то же самое что и тело сообщения.

Операция с байтовыми фрагментами может относиться к одному набору байт или к нескольким таким наборам в пределах одного объекта.
ranges-specifier = byte-ranges-specifier
byte-ranges-specifier = byte-sunit "=" byte-range-set
byte-range-set

= 1#( byte-range-spec | suffix-byte-range-spec )
byte-range-spec

= first-byte-pos "-" [last-byte-pos]
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT


Значение first-byte-pos в спецификации byte-range-spec указывает на относительное положение первого байта фрагмента. Значение last-byte-pos определяет относительное положение последнего байта фрагмента. Относительное положение начального байта равно нулю.

Если присутствует значение last-byte-pos, оно должно быть больше или равно значению first-byte-pos в спецификации byte-range-spec, в противном случае спецификация byte-range-spec не корректна. Получатель некорректной спецификации byte-range-spec должен ее игнорировать.

Если значение last-byte-pos отсутствует, или если значение больше или равно текущей длине тела объекта, значение last-byte-pos берется на единицу меньше текущего значения длины тела объекта в байтах.

При выборе last-byte-pos, клиент может ограничить число копируемых байт, если не известна длина объекта.

suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT

Спецификация suffix-byte-range-spec используется для задания суффикса тела объекта с длиной, заданной значением suffix-length. (То есть, эта форма специфицирует последние N байтов тела объекта.) Если объект короче заданной длины суффикса, то в качестве суффикса используется все тело объекта.



Примеры значений byte-ranges-specifier (предполагается, что длина тела объекта равна 10000):


  • Первые 500 байтов (относительные позиции 0-499, включительно): bytes=0-499


  • Вторые 500 байтов (относительные позиции 500-999, включительно): bytes=500-999


  • Последние 500 байтов (относительные позиции 9500-9999, включительно): bytes=-500


или
bytes=9500-


  • Первые и последние байты (байты 0 и 9999): bytes=0-0,-1


  • Несколько легальных, но неканонических спецификаций вторых 500 байт (относительные позиции 500-999, включительно): bytes=500-600,601-999; bytes=500-700,601-999


13.36.2. Запросы получения фрагментов

Информационные запросы HTTP, использующие условные или безусловные методы GET могут заказывать один или более субфрагментов объекта, а не целый объект, используя заголовок запроса Range:
Range = "Range" ":" ranges-specifier


Сервер может игнорировать заголовок Range. Однако исходные серверы HTTP/1.1 и промежуточные кэши должны поддерживать по возможности работу с фрагментами, так как Range поддерживает эффективное восстановление в случае частично неудачных пересылок больших объектов.

Если сервер поддерживает заголовки Range и специфицированный фрагмент или фрагменты подходят для данного объекта, то:


  • Присутствие заголовка Range в безусловном GET допускает модификацию того, что прислано. Другими словами отклик может содержать статусный код 206 (Partial Content) вместо 200 (OK).


  • Присутствие заголовка Range в условном GET (запрос использует If-Modified-Since, If-None-Match, If-Unmodified-Since и/или If-Match) модифицирует то, что прислано GET в случае успешного завершения при выполнении условия (TRUE). Это не влияет на отклик 304 (Not Modified), если условие не выполнено (FALSE).


В некоторых случаях более удобно использовать заголовок If-Range (см. раздел 13.27).

Если прокси, который поддерживает фрагменты, получает запрос Range, переадресует запрос внешнему серверу и получает в ответ весь объект, ему следует прислать запрашиваемый фрагмент клиенту.


Он должен запомнить весь полученный отклик в своем кэше, если отклик совместим с политикой записи в его кэш.

13.37. Поле Referer

Поле заголовка запроса Referer позволяет клиенту специфицировать (для пользы сервера) адрес (URI) ресурса, из которого был получен Request-URI. Заголовок запроса Referer позволяет серверу генерировать список обратных связей с ресурсами для интереса, ведения дневника, оптимизации кэширования и т.д.. Он позволяет также заставить работать устаревшие или дефектные связи. Поле Referer не должно посылаться, если Request-URI был получен от источника, который не имеет своего собственного URI, такого, например, как ввод с пользовательского терминала.
Referer = "Referer" ":" ( absoluteURI | relativeURI )


Пример:

Referer: http://www.w3.org/hypertext/DataSources/Overview.html

Если значением поля является частичный URI, его следует интерпретировать относительно Request-URI. URI не должен включать фрагментов.

Замечание. Так как первоисточник связи может быть конфиденциальной информацией или может раскрывать другой источник частной информации, настоятельно рекомендуется, чтобы пользователь имел возможность решать, посылать поле Referer или нет. Например, клиент-броузер может иметь кнопку-переключатель для открытого или анонимного просмотра, которая управляет активацией/дезактивацией посылки информации Referer и From.

13.38. Поле Retry-After

Поле заголовка отклика Retry-After может использоваться с кодом статуса 503 (Service Unavailable) с тем, чтобы указать, как еще долго данная услуга предполагается быть недоступной для запрашивающего клиента. Значением этого поля может быть либо дата HTTP либо целое число секунд (в десятичном исчислении) после отправки отклика.
Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )


Два примера использования поля

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

В последнем примере задержка равна двум минутам.

13.39. Поле Server

Поле заголовка отклика Server содержит информацию о программном обеспечении, используемым исходным сервером для обработки запросов.


Поле может содержать коды многих продуктов (раздел 2.8), комментарии, идентифицирующие сервер, и некоторые важные субпродукты. Коды программных продуктов перечисляются в порядке важности приложений.
Server = "Server" ":" 1*( product | comment )


Например:

Server: CERN/3.0 libwww/2.17

Если отклик переадресуется через прокси, приложение прокси не должно модифицировать заголовок отклика сервера. Вместо этого ему следует включить в отклик поле Via (как это описано в разделе 13.44).

Замечание. Раскрытие конкретной версии программного обеспечения сервера может облегчить атаки против программных продуктов, для которых известны уязвимые места. Разработчикам серверов рекомендуется сделать это поле конфигурируемой опцией.

13.40. Поле Transfer-Encoding (Транспортное кодирование)

Поле общего заголовка Transfer-Encoding указывает, какой тип преобразования (если таковое использовано) применен к телу сообщения, для того чтобы безопасно осуществить передачу между отправителем и получателем. Это поле отличается от Content-Encoding тем, что транспортное кодирование является параметром сообщения, а не объекта.

Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding

Транспортное кодирование определено в разделе 2.6. Например:

Transfer-Encoding: chunked

Многие старые приложения HTTP/1.0 не воспринимают заголовок Transfer-Encoding.

13.41. Заголовок Upgrade (Актуализация)

Общий заголовок Upgrade позволяет клиенту специфицировать то, какие дополнительные коммуникационные протоколы он поддерживает и хотел бы использовать, если сервер найдет их подходящими. Сервер должен использовать поле заголовка Upgrade в отклике 101 (Switching Protocols) для указания того, какие протоколы активны.
Upgrade = "Upgrade" ":" 1#product


Например:,

Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11

Поле заголовка Upgrade предназначено для обеспечения простого механизма перехода от протокола HTTP/1.1 к некоторым другим. Это достигается путем разрешения клиенту объявлять о намерении использовать другой протокол, например, более позднюю версию HTTP с большим старшим кодом версии, даже если текущий запрос выполнен с использованием HTTP/1.1.


Это облегчает переходы между несовместимыми протоколами за счет разрешения клиенту инициировать запрос в более широко поддерживаемом протоколе, в то же время, указывая серверу, что он предпочел бы использовать протокол "получше", если таковой доступен (где слово "получше" определяется сервером, возможно согласно природы метода и/или запрашиваемого ресурса).

Поле заголовка Upgrade воздействует только на переключающий протокол прикладного уровня транспортного слоя существующег соединения. Upgrade не может быть использовано для требования изменения протокола, его восприятие и использование сервером является опционным. Совместимость и природа прикладного уровня коммуникаций после смены протокола зависит исключительно от нового выбранного протокола, хотя первым действием после такой замены должен быть отклик на исходный запрос HTTP, содержащий поле заголовка Upgrade.

Поле Upgrade применимо только к текущему соединению. Следовательно, ключевое слово upgrade должно содержаться в поле заголовка Connection (раздел 13.10) всякий раз, когда поле Upgrade присутствует в сообщении HTTP/1.1.

Поле заголовка Upgrade не может использоваться для указания смены протокола в другом соединении. Для этой цели более приемлемы отклики переадресации с кодами 301, 302, 303 или 305.

Эта спецификация определяет протокол с именем "HTTP" при работе с семейством протоколов для передачи гипертекста (Hypertext Transfer Protocols), как это определено в правилах работы с версиями HTTP раздела 2.1 и для будущих усовершенствований этой спецификации. В качестве имени протокола может использоваться любая лексема, однако она будет работать, только если клиент и сервер ассоциируют это имя с одним и тем же протоколом.

13.42. Поле User-Agent (Агент пользователя)

Поле заголовка отклика User-Agent содержит информацию об агенте пользователя, инициировавшем запрос. Это нужно для целей сбора статистических данных, отслеживания нарушений протокола и автоматического распознавания агентов пользователя.


Агентам пользователя рекомендуется включать это поле в запросы. Поле может содержать несколько кодов продуктов (раздел 2.8), комментарии, идентифицирующие агента и любые субпродукты, которые образуют существенную часть агента пользователя. Согласно договоренности коды программных продуктов перечисляются в порядке их важности для идентифицируемого приложения.
User-Agent

= "User-Agent" ":" 1*( product | comment )


Например:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

13.43. Поле Vary

Поле заголовка отклика Vary используется сервером для того, чтобы сигнализировать о том, что отклик выбран из числа имеющихся представлений с помощью механизма согласования под управлением сервера (раздел 11). Имена полей, перечисленные в заголовках Vary, являются такими заголовками запроса. Значение поля Vary указывает на то, что данный набор полей заголовка ограничивает пределы, в которых могут варьироваться представления, или что пределы вариации не специфицированы ("*") и, таким образом, могут модифицироваться в широких пределах для будущих запросов.
Vary = "Vary" ":" ( "*" | 1#field-name )


Сервер HTTP/1.1 должен включать соответствующее поле заголовка Vary в любой кэшируемый отклик, который является субъектом, управляющим процессом согласования. Такая схема позволяет кэшу правильно интерпретировать будущие запросы к заданному ресурсу и информирует пользователя о согласовании доступа к ресурсу. Серверу следует включить соответствующее поле заголовка Vary в некэшируемый отклик, который является субъектом, управляющим согласованием, так как это может предоставить агенту пользователя полезную информацию о пределах вариации отклика.

Набор полей заголовка, перечисленных в поле Vary известен как "выбирающие" заголовки запроса.

Когда кэш получает последующий запрос, чей Request-URI специфицирует одну или более записей кэша, включая заголовок Vary, кэш не должен использовать такую запись для формирования отклика на новый запрос.


Он это должен делать, если только все заголовки, перечисленные в кэшированном заголовке Vary, присутствуют в новом запросе и все заголовки отбора предшествующих запросов совпадают с соответствующими заголовками нового запроса.

Сортирующие заголовки от двух запросов считаются соответствующими, тогда и только тогда, когда сортирующие заголовки первого запроса могут быть преобразованы в сортирующие заголовки второго запроса с помощью добавления или удаления строчных пробелов LWS (Linear White Space) в местах, где это допускается соответствующими правилами BNF (Backus-Naur Form) и/или, комбинируя несколько полей заголовка согласно требованиям на построение сообщения из раздела 3.2.

Vary "*" означает, что не специфицированные параметры, возможно отличающиеся от содержащихся в полях заголовка (напр., сетевой адрес клиента), играют роль при выборе представления отклика. Последующие запросы данного ресурса могут быть правильно интерпретированы только исходным сервером, а кэш должен переадресовать запрос (возможно условно), даже когда он имеет свежий кэшированный отклик для данного ресурса. Об использовании заголовка кэшами см. раздел 12.6.

Значение поля Vary, состоящее из списка имен полей сигнализирует о том, что представление, выбранное для отклика, базируется на алгоритме выбора, который рассматривает только значения перечисленные в поле заголовка запроса. Кэш может предполагать, что тот же выбор будет сделан для будущих запросов с теми же значениями имен полей, для периода времени, в течение которого отклик остается свежим.

Имена полей не ограничены набором стандартных полей заголовков запросов, определенных в данной спецификации. Имена полей могут быть записаны строчными или прописными буквами.

13.44. Поле Via

Поле общего заголовка Via должно быть использовано шлюзами или прокси для указания промежуточных протоколов и получателей на пути от агента пользователя к серверу, которому адресован запрос, и между исходным сервером и клиентом в случае отклика.


Это аналогично полю "Received" документа RFC 822 и предназначено для использования при трассировке переадресаций сообщений, исключения петель запроса и идентификации протокольных возможностей всех отправителей вдоль цепочки запрос/отклик.
Via = "Via" ":" 1#( received-protocol received-by [ comment ] )
received-protocol

= [ protocol-name "/" ] protocol-version
protocol-name = token
protocol-version = token
received-by = ( host [ ":" port ] ) | pseudonym
pseudonym = token


Запись "received-protocol" указывает версию протокола в сообщении, полученном сервером или клиентом вдоль цепочки запрос/отклик. Версия received-protocol добавляется к значению поля Via, когда сообщение переадресуется, так что информация о возможностях протоколов предыдущих приложений остается прозрачной для всех получателей.

Запись "protocol-name" является опционной, тогда и только тогда, когда это "HTTP". Поле "received-by" обычно соответствует ЭВМ и номеру порта сервера получателя или клиента, который переадресует сообщение. Однако, если настоящее имя ЭВМ считается конфиденциальной информацией, оно может быть заменено псевдонимом. Если номер порта не задан, можно предполагать, что используется значение по умолчанию для данного протокола (received-protocol).

Значения поля Via представляет каждый прокси или шлюз, который переадресовывал сообщение. Каждый получатель должен присоединить свою информацию так, что конечный результат оказывается упорядоченным согласно последовательности переадресующих приложений.

Комментарии могут быть использованы в поле заголовка Via для идентификации программ получателя прокси или шлюза аналогично полям User-Agent и Server header. Однако, все комментарии в поле Via являются опционными и могут быть удалены любым получателем перед тем, как переадресовать сообщение.

Например, сообщение-запрос может быть послано от агента пользователя HTTP/1.0 программе внутреннего прокси с именем "fred", которая использует HTTP/1.1 для того, чтобы переадресовать запрос общедоступному прокси с именем nowhere.com, который завершает процесс переадресации запроса исходному серверу www.ics.uci.edu.


Запрос, полученный www.ics.uci. edu будет тогда иметь следующее поле заголовка Via:

Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)

Прокси и шлюзы, используемые как средства сетевой защиты (firewall) не должны по умолчанию переадресовывать имена ЭВМ и портов в пределах области firewall. Эта информация может передаваться, если это непосредственно позволено. Если это не разрешено, запись "received-by" для ЭВМ в зоне действия firewall должна быть заменена соответствующим псевдонимом.

Для организаций, которые имеют жесткие требования к защите конфиденциальности и сокрытию внутренней структуры, прокси может комбинировать субпоследовательность поля заголовка Via с идентичными значениями "received-protocol" в единую запись. Например,

Via: 1.0 vanya, 1.1 manya, 1.1 dunya, 1.0 sonya

Приложениям не следует комбинировать несколько записей, если они только не находятся под единым административным контролем и имена ЭВМ уже заменены на псевдонимы. Приложения не должны комбинировать записи, которые имеют различные значения "received-protocol".

13.45. Поле Warning (Предупреждение)

Поле заголовка отклика Warning используется для переноса дополнительной информации о состоянии отклика, которая может отражать статусный код. Эта информация обычно служит для предупреждения о возможной потере семантической прозрачности из-за операций кэширования. Заголовки Warning посылаются с откликами, используя:
Warning

= "Warning" ":" 1#warning-value
warning-value = warn-code SP warn-agent SP warn-text
warn-code = 2DIGIT
warn-agent = ( host [ ":" port ] ) | pseudonym


; имя или псевдоним сервера, добавившего заголовок Warning, предназначенный для целей отладки
warn-text = quoted-string


Отклик может нести в себе более одного заголовка Warning.

Запись warn-text производится на естественном языке и с применением символьного набора, приемлемого для принимающего отклик лица. Это решение может базироваться на какой-то имеющейся информации, такой как положение кэша или пользователя, поле запроса Accept-Language, поле отклика Content-Language и т.д.


Языком по умолчанию является английский, а символьным набором - ISO-8859-1.

Если используется символьный набор отличный от ISO-8859-1, он должен быть закодирован в warn-text с использованием метода, описанного в RFC-1522 [14].

Любой сервер или кэш может добавить заголовки Warning к отклику. Новые заголовки Warning должны добавляться после любых существующих заголовков Warning. Кэш не должен уничтожать какие-либо заголовки, которые он получил в отклике. Однако, если кэш успешно перепроверил запись, ему следует удалить все заголовки Warning, присоединенные ранее, за исключением специальных кодов Warning. Он должен добавить к записи новые заголовки Warning, полученные с откликом перепроверки. Другими словами заголовками Warning являются те, которые были бы получены в отклике на запрос в данный момент.

Когда к отклику подключено несколько заголовков Warning, агенту пользователя следует отображать их столько, сколько возможно, для того чтобы они появились в отклике. Если невозможно отобразить все предупреждения, агент пользователя должен следовать следующим эвристическим правилам:


  • Предупреждения, которые появляются в отклике раньше, имеют приоритет перед теми, что появляются позже.


  • Предупреждения, с предпочитаемым пользователем символьным набором имеют приоритет перед предупреждениями с другими наборами, но с идентичными warn-codes и warn-agents.


Системы, которые генерируют несколько заголовков Warning, должны упорядочить их с учетом ожидаемого поведения агента пользователя.

Далее представлен список определенных в настоящее время кодов предупреждений, каждый из которых сопровождается рекомендуемым текстом на английском языке и описанием его значения.

10 Response is stale (отклик устарел)

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

11 Revalidation failed (перепроверка пригодности неудачна)



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

12 Disconnected operation (работа в отключенном от сети состоянии)

Следует включать, если кэш намерено отключен от остальной сети на определенный период времени.

13 Heuristic expiration (эвристическое завершение периода пригодности)

Должно включаться, если кэш эвристически выбрал время жизни больше 24 часов, а возраст отклика превышает эту величину.

14 Transformation applied (применено преобразование)

Должно добавляться промежуточным кэшем или прокси, если он использует какое-либо преобразование, изменяющее кодировку содержимого (как это специфицировано в заголовке Content-Encoding) или тип среды (как это описано в заголовке Content-Type) отклика, если только этот код предупреждения не присутствует уже в отклике.

99 Разные предупреждения

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

13.46. Поле WWW-Authenticate

Поле заголовка отклика WWW-Authenticate должно включаться в сообщения откликов со статусным кодом 401 (Unauthorized). Значение поля содержит, по крайней мере, одно требование, которое указывает на схему идентификации и параметры, применимые для Request-URI.

WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge

Процесс авторизации доступа HTTP описан в разделе 10. Агенты пользователя должны проявлять особую тщательность при разборе значения поля WWW-Authenticate, если оно содержит более одного требования, или если прислан более чем одно поле заголовка WWW-Authenticate, так как содержимое требования может само содержать список параметров идентификации, элементы которого разделены запятыми.



14. Соображения безопасности

Этот раздел предназначен для того, чтобы проинформировать разработчиков приложений, поставщиков информации и пользователей об ограничениях безопасности в HTTP/1.1, как это описано в данном документе. Обсуждение не включает определенные решения данных проблем, но рассматриваются некоторые предложения, которые могут уменьшить риск.

14.1. Аутентификация клиентов

Базовая схема идентификации не предоставляет безопасного метода идентификации пользователя, не обеспечивает она и какох-либо средств защиты объектов, которые передаются открытым текстом по используемым физическим сетям. HTTP не мешает внедрению дополнительных схем идентификации и механизмов шифрования или других мер, улучшающих безопасность системы (например, SSL или одноразовых паролей).

Наиболее серьезным дефектом базового механизма идентификации является то, что пароль пользователя передается по сети в незашифрованном виде.

Так как базовая идентификация предусматривает пересылку паролей открытым текстом, она никогда не должна использоваться (без улучшения) для работы с конфиденциальной информацией.

Обычным назначением базовой идентификации является создание информационной (справочной) среды, которая требует от пользователя его имени и пароля, например, для сбора точной статистики использования ресурсов сервера. При таком использовании предполагается, что не существует никакой опасности даже в случае неавторизованного доступа к защищенному документу. Это правильно, если сервер генерирует сам имя и пароль пользователя и не позволяет ему выбрать себе пароль самостоятельно. Опасность возникает, когда наивные пользователи часто используют один и тот же пароль, чтобы избежать необходимости внедрения многопарольной системы защиты.

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


Многие из этих паролей могут принадлежать удаленным пользователям. Собственник или администратор такой системы может помимо своей воли оказаться ответственным за нарушения безопасности сохранения информации.

Базовая идентификация уязвима также для атак поддельных серверов. Когда пользователь связывается с ЭВМ, содержащей информацию, защищенную с использованием базовой системой идентификации, может так получиться, что в действительности он соединяется с сервером-злоумышленником, целью которого является получение идентификационных параметров пользователя (например, имени и пароля). Этот тип атак не возможен при использовании идентификации с помощью дайджестов [32]. Разработчики серверов должны учитывать возможности такого рода атак со стороны ложных серверов или CGI-скриптов. В частности, очень опасно для сервера просто прерывать связь со шлюзом, так как этот шлюз может тогда использовать механизм постоянного соединения для выполнения нескольких процедур с клиентом, исполняя роль исходного сервера, так что это незаметно клиенту.

14.2. Предложение выбора схемы идентификации

Сервер HTTP/1.1 может прислать несколько требований с откликом 401 (Authenticate) и каждое требование может использовать разную схему. Порядок присылки требований соответствует шкале предпочтений сервера. Сервер должен упорядочит требования так, чтобы наиболее безопасная схема предлагалась первой. Агент пользователя должен выбрать первую понятную ему схему.

Когда сервер предлагает выбор схемы идентификации, используя заголовок WWW-Authenticate, безопасность может быть нарушена только за счет того, что злонамеренный пользователь может перехватить набор требований и попытаться идентифицировать себя, используя саму слабую схему идентификации. Таким образом, упорядочение служит более для защиты идентификационных параметров пользователя, чем для защиты информации на сервере.

Возможна атака MITM (man-in-the-middle - "человек в середине"), которая заключается в добавлении слабой схемы идентификации к списку выбора в надежде на то, что клиент выберет именно ее и раскроет свой пароль.


По этой причине клиент должен всегда использовать наиболее строгую схему идентификации из предлагаемого списка.

Еще эффективнее может быть MITM-атака, при которой удаляется весь список предлагаемых схем идентификации, и вставляется вызов, требующий базовой схемы идентификации. По этой причине агенты пользователя, обеспокоенные таким видом атак, могут запомнить самую строгую схему идентификации, которая когда-либо запрашивалась данным сервером, и выдавать предупреждение, которое потребует подтверждения пользователя при использовании более слабой схемы идентификации. Особенно хитроумный способ реализации MITM-атаки является предложение услуг "свободного" кэширования для доверчивых пользователей.

14.3. Злоупотребление служебными (Log) записями сервера

Сервер должен оберегать информацию о запросах пользователя, о характере его интересов (такая информация доступна в дневнике операций сервера). Эта информация является, очевидно, конфиденциальной по своей природе и работа с ней во многих странах ограничена законом. Люди, использующие протокол HTTP для получения данных, являются ответственными за то, чтобы эта информация не распространялась без разрешения лиц, кого эта информация касается.

14.4. Передача конфиденциальной информации

Подобно любому общему протоколу передачи данных, HTTP не может регулировать содержимое передаваемых данных, не существует методов определения степени конфиденциальности конкретного фрагмента данных в пределах контекста запроса. Следовательно, приложения должны предоставлять как можно больше контроля провайдеру информации. Четыре поля заголовка представляют интерес с этой точки зрения: Server, Via, Referer и From. Раскрытие версии программного обеспечения сервера может привести к большей уязвимости машины сервера к атакам на программы с известными слабостями. Разработчики должны сделать поле заголовка Server конфигурируемой опцией. Прокси, которые служат в качестве сетевого firewall, должны предпринимать специальные предосторожности в отношении передачи информации заголовков, идентифицирующей ЭВМ, за пределы firewall.


В частности они должны удалять или замещать любые поля Via, созданные в пределах firewall. Хотя поле Referer может быть очень полезным, его мощь может быть использована во вред, если данные о пользователе не отделены от другой информации, содержащейся в этом поле. Даже когда персональная информация удалена, поле Referer может указывать на URI частных документов, чья публикация нежелательна. Информация, посланная в поле From, может вступать в конфликт с интересами конфиденциальности пользователя или с политикой безопасности его домена, и, следовательно, она не должна пересылаться и модифицироваться без прямого разрешения пользователя. Пользователь должен быть способен установить содержимое этого поля, в противном случае оно будет установлено равным значению по умолчанию. Мы предлагаем, хотя и не требуем, чтобы предоставлялся удобный интерфейс для пользователя, который позволяет активировать и дезактивировать посылку информации полей From и Referer.

14.5. Атаки, основанные на именах файлов и проходов

Реализации исходных серверов HTTP должна быть тщательной, чтобы ограничить список присылаемых HTTP документов теми, которые определены для этого администратором сервера. Если сервер HTTP транслирует HTTP URI непосредственно в запросы к файловой системе, сервер должен следить за тем, чтобы не пересылать файлы клиентам HTTP, для этого не предназначенные. Например, UNIX, Microsoft Windows и другие операционные системы используют ".." как компоненту прохода, чтобы указать уровень каталога выше текущего. В такой системе сервер HTTP должен запретить любую подобную в Request-URI, если она позволяет доступ к ресурсу за пределами того, что предполагалось. Аналогично, файлы, предназначенные только для внутреннего использования сервером (такие как файлы управления доступом, конфигурационные файлы и коды скриптов) должны быть защищены от несанкционированного доступа, так как они могут содержать конфиденциальную информацию. Практика показала, что даже незначительные ошибки в реализации сервера HTTP могут привести к рискам безопасности.



14.6. Персональная информация

Клиентам HTTP небезразличнен доступ к некоторым данным (например, к имени пользователя, IP-адресу, почтовому адресу, паролю, ключу шифрования и т.д.). Система должна быть тщательно сконструирована, чтобы предотвратить непреднамеренную утечку информации через протокол HTTP. Мы настоятельно рекомендуем, чтобы был создан удобный интерфейс для обеспечения пользователя возможностями управления распространением такой информации.

14.7. Аспекты конфиденциальности, связанные с заголовками Accept

Заголовок запроса Accept может раскрыть информацию о пользователе всем серверам, к которым имеется доступ. В частности, заголовок Accept-Language может раскрыть информацию, которую пользователь, возможно, рассматривает как конфиденциальную. Так, например, понимание определенного языка часто строго коррелируется с принадлежностью к определенной этнической группе. Агентам пользователя, которые предлагают возможность конфигурирования содержимого заголовка Accept-Language, настоятельно рекомендуется посылать сообщение пользователю о том, что в результате может быть потеряна конфиденциальность определенных данных. Подходом, который ограничивает потерю конфиденциальности для агента пользователя, может быть отказ от посылки заголовков Accept-Language по умолчанию. Предполагается при этом каждый раз консультироваться с пользователем относительно возможности посылки этих данных серверу. Пользователь будет принимать решение о посылке Accept-Language, лишь убедившись на основании содержимого заголовка отклика Vary в том, что такая посылка существенно улучшит качество обслуживания.

Для многих пользователей, которые размещены не за прокси, сетевой адрес работающего агента пользователя может также использоваться как его идентификатор. В среде, где прокси используются для повышения уровня конфиденциальности, агенты пользователя должны быть достаточно консервативны в предоставлении опционного конфигурирования заголовков доступа конечным пользователям. В качестве крайней меры обеспечения защиты прокси могут фильтровать заголовки доступа для передаваемых запросов.


Главной целью агентов пользователя, которые предоставляют высокий уровень конфигурационных возможностей, должно быть предупреждение пользователя о возможной потере конфиденциальности.

14.8. Фальсификация DNS

Клиенты, интенсивно использующие HTTP обмен со службой имен домена (Domain Name Service), обычно предрасположены к атакам, базирующимся на преднамеренном некорректном соответствии IP адресов и DNS имен. Клиенты должны быть осторожны относительно предположений, связанных с ассоциаций IP адресов и DNS имен.

В частности, клиенту HTTP следует полагаться на его сервер имен для подтверждения соответствия IP адресов и DNS имен, а не слепо кэшировать результаты предшествующих запросов. Многие платформы могут кэшировать такие запросы локально и это надо использовать, конфигурируя их соответствующим образом. Такие запросы должны кэшироваться, однако только на период, пока не истекло время жизни этой информации.

Если клиенты HTTP кэшируют результат DNS-запроса для улучшения рабочих характеристик, они должны отслеживать пригодность этих данных с учетом времени жизни, объявляемого DNS-сервером.

Если клиенты HTTP не следуют этому правилу, они могут быть мистифицированы, когда изменится IP-адрес доступного ранее сервера. Так как смена адресов в сетях будет в ближайшее время активно развиваться (Ipv6 !), такого рода атаки становятся все более вероятными.

Данное требование улучшает работу клиентов, в том числе с серверами, имеющими идентичные имена.

14.9. Заголовки Location и мистификация

Если один сервер поддерживает несколько организаций, которые не доверяют друг другу, тогда он должен проверять значения заголовков Location и Content-Location в откликах, которые формируются под управлением этих организаций. Это следует делать, чтобы быть уверенным, что они не пытаются провести какие-либо операции над ресурсами, доступ к которым для них ограничен.

15. Библиография

[1]

Alvestrand, H., "Tags for the identification of languages", RFC 1766, UNINETT, March 1995.
[2]

Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey, D., and B. Alberti. "The Internet Gopher Protocol: (a distributed document search and retrieval protocol)", RFC 1436, University of Minnesota, March 1993
[3]

Berners-Lee, T., "Universal Resource Identifiers in WWW", A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the World-Wide Web", RFC 1630, CERN, June 1994
[4]

Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, CERN, Xerox PARC, University of Minnesota, December 1994
[5]

Berners-Lee, T., and D. Connolly, "HyperText Markup Language Specification - 2.0", RFC 1866, MIT/LCS, November 1995
[6]

Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0.", RFC 1945 MIT/LCS, UC Irvine, May 1996
[7]

Freed, N., and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, Innosoft, First Virtual, November 1996.
[8]

Braden, R., "Requirements for Internet hosts - application and support", STD3, RFC 1123, IETF, October 1989
[9]

Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, UDEL, August 1982
[10]

Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R., Sui, J., and M. Grinbaum. "WAIS Interface Protocol Prototype Functional Specification", (v1.5), Thinking Machines Corporation, April 1990
[11]

Fielding, R., "Relative Uniform Resource Locators", RFC 1808, UC Irvine, June 1995
[12]

Horton, M., and R. Adams. "Standard for interchange of USENET messages", RFC 1036, AT&T Bell Laboratories, Center for Seismic Studies, December 1987
[13]

Kantor, B., and P. Lapsley. "Network News Transfer Protocol." A Proposed Standard for the Stream-Based Transmission of News", RFC 977, UC San Diego, UC Berkeley, February 1986
[14]

Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, University of Tennessee, November 1996
[15]

Nebel, E., and L. Masinter. "Form-based File Upload in HTML", RFC 1867, Xerox Corporation, November 1995.
[16]

Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, USC/ISI, August 1982
[17]

Postel, J., "Media Type Registration Procedure", RFC 2048, USC/ISI, November 1996
[18]

Postel, J., and J. Reynolds, "File Transfer Protocol (FTP)", STD 9, RFC 959, USC/ISI, October 1985
[19]

Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC1700, USC/ISI, October 1994
[20]

Sollins, K., and L. Masinter, "Functional Requirements for Uniform Resource Names", RFC 1737, MIT/LCS, Xerox Corporation, December 1994
[21]

US-ASCII. Coded Character Set - 7-Bit American Standard Code for Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986
[22]

ISO-8859. International Standard -- Information Processing -- 8-bit Single-Byte Coded Graphic Character Sets


Part 1: Latin alphabet No. 1, ISO 8859-1:1987


Part 2: Latin alphabet No. 2, ISO 8859-2, 1987


Part 3: Latin alphabet No. 3, ISO 8859-3, 1988


Part 4: Latin alphabet No. 4, ISO 8859-4, 1988


Part 5: Latin/Cyrillic alphabet, ISO 8859-5, 1988


Part 6: Latin/Arabic alphabet, ISO 8859-6, 1987


Part 7: Latin/Greek alphabet, ISO 8859-7, 1987


Part 8: Latin/Hebrew alphabet, ISO 8859-8, 1988


Part 9: Latin alphabet No. 5, ISO 8859-9, 1990
[23]

Meyers, J., and M. Rose "The Content-MD5 Header Field", RFC1864, Carnegie Mellon, Dover Beach Consulting, October, 1995
[24]

Carpenter, B., and Y. Rekhter, "Renumbering Needs Work", RFC 1900, IAB, February 1996.
[25]

Deutsch, P., "GZIP file format specification version 4.3." RFC1952, Aladdin Enterprises, May 1996
[26]

Venkata N. Padmanabhan and Jeffrey C. Mogul. Improving HTTP Latency. Computer Networks and ISDN Systems, v. 28, pp. 25-35, Dec. 1995. Slightly revised version of paper in Proc. 2nd International WWW Conf. '94: Mosaic and the Web, Oct. 1994, which is available at http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/ mogul/HTTPLatency.html.
[27]

Joe Touch, John Heidemann, and Katia Obraczka, "Analysis of HTTP Performance", , USC/Information Sciences Institute, June 1996
[28]

Mills, D., "Network Time Protocol, Version 3, Specification, Implementation and Analysis", RFC 1305, University of Delaware, March 1992
[29]

Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3." RFC 1951, Aladdin Enterprises, May 1996
[30]

Spero, S., "Analysis of HTTP Performance Problems" .
[31]

Deutsch, P., and J-L. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, Aladdin Enterprises, Info-ZIP, May 1996
[32]

Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., Luotonen, A., Sink, E., and L. Stewart, "An Extension to HTTP : Digest Access Authentication", RFC 2069, January 1997



Содержание раздела