Интегрированные сети ISDN

         

UA – агент пользователя



Рисунок 4.5.6.1.3. UA – агент пользователя

На рисунке показаны три промежуточные ступени (A, B, и C) между агентом пользователя (UA) и базовым сервером (O). Запрос или отклик, двигаясь по этой цепочке, должен пройти четыре различных соединительных сегмента. Это обстоятельство крайне важно, так как некоторые опции HTTP применимы только для ближайших соединений. Хотя схема линейна, на практике узлы могут участвовать в большом числе других взаимодействий. Например, B может получать запросы от большого числа клиентов помимо A, и переадресовывать запросы к другим серверам кроме C.

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

В действительности имеется широкое разнообразие архитектур и конфигураций буферных запоминающих устройств и прокси, разрабатываемых в настоящее время или уже доступных через World Wide Web. Эти системы включают иерархии прокси-серверов национального масштаба, задачей которых является сокращение трансокеанского трафика, системы, которые обслуживают широковещательные и мультикастинговые обмены, организации, распространяющие фрагменты информации с CD-ROM, занесенной в кэши и т. д.. HTTP-системы, используются в корпоративных сетях Интранет с большими пропускными способностями и перемежающимися соединениями. Целью HTTP/1.1 является поддержка широкого разнообразия уже существующих систем и расширение возможностей будущих приложений в отношении надежности и адаптируемости.

Коммуникации HTTP обычно реализуются через соединения TCP/IP. Порт по умолчанию имеет номер 80, но и другие номера портов вполне допустимы. Это не исключает использования HTTP поверх любого другого протокола в Интернет, или других сетей.
HTTP предполагает надежное соединение; применим любой протокол, который может гарантировать корректную доставку сообщений.

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

4.5.6.1.1. Соглашения по нотации и общая грамматика

1.1. Расширенные BNF


Все механизмы, специфицированные в данном документе, описаны с использованием обычного текста и расширенных форм Бахуса-Наура BNF (Backus-Naur Form; см. RFC 822). Пользователи должны быть знакомы с этой нотацией для понимания данной спецификации. Расширение BNF включает в себя следующие конструкции:

name = definition

Имя правила не требует помещения в угловые скобки. Некоторые базовые правила записываются прописными буквами, например, SP, LWS, HT, CRLF, DIGIT, ALPHA и пр.

"literal"

Двойные кавычки используются для выделения символьного текста.

rule1 | rule2



Элементы, разделенные вертикальной чертой, ("|") являются альтернативными, например, "yes | no" допускает yes или no (да или нет).

(rule1 rule2)

Элементы, помещенные в круглые скобки, рассматриваются как один элемент. Так, "(elem (foo | bar) elem)" допускают последовательности "elem foo elem" и "elem bar elem".

*rule

Символ "*", предшествующий элементу, указывает на повторение. Полная форма "*element" указывает как минимум на и как максимум повторений элемента. Значения по умолчанию равны 0 и бесконечности, так что "*( элемент)" позволяет любое число, включая ноль; "1*element" требует по меньшей мере один; а "1*2element" допускает один или два.

[rule]

В квадратные скобки заключаются опционные элементы; "[foo bar]" эквивалентно "*1(foo bar)".

N rule

Специальный повтор: "(элемент)" эквивалентно "*(элемент)"; то есть, точно (element).


Таким образом, 2DIGIT является 2-значным числом, а 3ALPHA представляет собой строку из трех буквенных символов.

#rule

Конструкция "#" определена подобно "*", для описания списка элементов. Полная форма имеет вид "#element ", отмечая, по меньшей мере и по большей элементов, отделенных друг от друга одной или более запятыми (",") и опционно строчным пробелом (LWS – Linear White Space). Это делает обычную форму списков очень простой. Запись "( *LWS элемент *( *LWS "," *LWS элемент)) " может быть представлена как "1#element". Всюду, где используется эта конструкция, допускаются нулевые элементы, но они не учитываются при подсчете элементов. То есть, допускается запись "(элемент), (элемент) ", но число элементов при этом считается равным двум. Следовательно, там, где необходим хотя бы один элемент, должен присутствовать, по крайней мере, один ненулевой элемент. Значениями по умолчанию являются 0 и бесконечность, таким образом "#элемент" позволяет любое число, включая нуль; "1#элемент" требует, по меньшей мере один, а "1#2элемент" допускает один или два.

   ; комментарий

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

implied *LWS

Грамматика, описанная в данной спецификации, ориентирована на слова. Если не оговорено обратное, строчный пробел (LWS) может быть заключен между любыми двумя соседними словами (лексема или заключенная в кавычки строка), и между смежными лексемами (token) и разделителями (TSpecials) без изменения интерпретации поля. По крайней мере один разграничитель (TSpecials) должен присутствовать между любыми двумя лексемами, так как они иначе будут интерпретироваться как одна.

1.2. Основные правила

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

OCTET =
CHAR =
UPALPHA =
LOALPHA = < любая строчная буква US-ASCII "a".."z">
ALPHA = UPALPHA | LOALPHA (строчная или прописная буква)
DIGIT =
CTL =
CR =
LF =
SP =
HT =
=
<


/p> HTTP/1. 1 определяет последовательность CR LF, как маркер конца для всех протокольных элементов, за исключением тела элемента. Маркер конца строки в пределах тела объекта определен соответствующим типом среды.

CRLF = CR LF
HTTP/1.1 заголовки могут занимать несколько строк, если продолжение строки начинается с пробела или символа горизонтальной табуляции. Все строчные пробелы имеют ту же семантику, что и обычный пробел (SP).

LWS = [CRLF] 1*( SP | HT )
Правило TEXT используется только для содержимого описательных полей и значений, которые не предполагается передавать интерпретатору сообщений. Слова *TEXT могут содержать символы из символьного набора, не совпадающего с ISO 8859-1 [22], только когда они закодированы согласно правилам RFC-1522 [14].

TEXT =
В некоторых протокольных элементах используются шестнадцатеричные цифровые символы.

HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
Многие значения полей заголовков HTTP/1.1 состоят из слов, разделенных LWS или специальными символами. Эти специальные символы должны представлять собой строки, заключенные в кавычки, чтобы использоваться в качестве значения параметра.

Token = 1*
Tspecials = "(" | ")" | "" | "@"
| "," | ";" | ":" | "\" |
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
Комментарии могут быть включены в некоторые поля HTTP заголовков, при этом текст комментария заключается в скобки. Комментарии допустимы только для полей, содержащих "comment", как часть описания поля. В других полях скобки рассматриваются как элемент содержимого поля.

Комментарий = "(" *( ctext | комментарий) ")"
ctext =
Строка текста воспринимается как одно слово, если она помещена в двойные кавычки.



quoted-string = ( *(qdtext) )
qdtext = >
Символ обратная косая черта ("\") может использоваться вместо кавычки внутри закавыченного текста или в структурах комментариев.

quoted-pair = "\" CHAR
4.5.6.1.2. Параметры протокола

2.1. Версия HTTP

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

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

Версия HTTP-сообщения указывается в поле HTTP-Version в первой строке сообщения.

HTTP Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
Заметьте, что числа major и minor должны рассматриваться как независимые целые, так что каждое из них может быть увеличено за пределы одной цифры. Таким образом, HTTP/2.4 является более низкой версией, чем HTTP/2.13, которая в свою очередь ниже, чем HTTP/12.3. Начальные нули должны игнорироваться и не пересылаться

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

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


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

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

2.2. Универсальные идентификаторы ресурсов (URI)

URI известен под многими именами: WWW адрес, универсальный идентификатор документа (Universal Document Identifiers), универсальный идентификатор ресурса (Universal Resource Identifiers), и, наконец, универсальный локатор ресурса URL (Uniform Resource Locators; тождество URI и URL сомнительно, так как URL является частным случаем URI (примечание переводчика)) и универсальное имя ресурса (URN). Что касается HTTP, универсальный идентификатор ресурса представляет собой форматированную строку символов, которая идентифицирует имя, положение или какие-то еще характеристики ресурса.

2.2.1. Общий синтаксис

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

URI = ( absoluteURI | relativeURI ) [ "#" фрагмент ]
AbsoluteURI = схема ":" *( uchar | reserved )
RelativeURI = net_path | abs_path | rel_path
net_path = "//" net_loc [ abs_path ]
abs_path = "/" rel_path
rel_path = [ проход ] [ ";" params ] [ "?" query ]
path = fsegment *( "/" сегмент )
fsegment = 1*pchar
segment = *pchar
params = param *( ";" param )
param = *( pchar | "/" )
scheme = 1*( ALPHA | DIGIT | "+" | "-" | "." )
net_loc = *( pchar | ";" | "?" )
query = *( uchar | reserved )
fragment = *( uchar | reserved )
pchar = uchar | ":" | "@" | "&" | "=" | "+"
uchar = unreserved | escape
unreserved = ALPHA | DIGIT | safe | extra | national
escape = "%" HEX HEX
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra = "!" | "*" | "'" | "(" | ")" | ","
safe = "$" | "-" | "_" | "."
unsafe = CTL | SP | | "#" | "%" | ""
national =
<


/p> Более детальную информацию о синтаксисе и семантике URL можно найти в RFC-1738 [4] и RFC-1808 [11]. Приведенные выше BNF включают в себя национальные символы, недопустимые в URL, так как это специфицировано в RFC 1738, так как серверам HTTP не запрещено использование любых наборов символов, допустимых в rel_path частях адресов, HTTP-прокси могут получить запросы URI, не определенные в рамках RFC-1738.

Протокол HTTP не устанавливает каких-либо ограничений на длину URI. Серверы должны быть способны обрабатывать URI любых ресурсов, имеющих любую длину. Сервер должен выдать отклик 414 (Request-URI Too Long – URI запроса слишком длинен), если URI длиннее, чем может обработать сервер (см. раздел 9.4.15).

Замечание: Серверы должны избегать использования URI длиннее 255 байт, так как некоторые старые клиенты или прокси-приложения не могут корректно работать с такими длинами.

2.2.2. HTTP URL

Схема "HTTP" используется для локализации сетевых ресурсов с помощью протокола HTTP. Далее определены синтаксис и семантика HTTP URL, зависящие от схемы.

http_URL = "http:" "//" host [ ":" port ] [ abs_path ]
host =
port = *DIGIT
Если номер порта не указан, предполагается порт 80. Семантика устроена так, что идентифицированный ресурс размещается на сервере, который ожидает TCP-соединения через порт данной ЭВМ, а Request-URI для ресурса находится в abs_path. Использование IP адресов в URL следует избегать всюду, где это возможно (см. RFC-1900 [24]). Если abs_path в URL отсутствует, он должен считаться равным "/", в случае, если он используется в качестве Request-URI для ресурса (раздел 4.1.2).

2.2.3. Сравнение URI

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

  • Номер порта не указан, тогда для данного URI берется значение по умолчанию;


  • Сравнение имен ЭВМ и схем не должно быть чувствительным к строчным/прописным буквам;




  • Пустой abs_path эквивалентен abs_path "/".


  • Символы, отличные от типов "reserved" и "unsafe" устанавливаются равными их эквивалентам в кодировке ""%" HEX HEX".

    Например, следующие три URI являются эквивалентными:

    http://abc.com:80/~smith/home.html

    http://ABC.com/%7Esmith/home.html

    http://ABC.com:/%7Esmith/home.html

    3.3. Форматы даты/времени

    3.3.1. Полная дата

    HTTP приложения допускают три различных формата для представления метки времени и даты:

    Sun, 06 Nov 1994 08:49:37 GMT ; RFC-822, актуализировано в RFC-1123

    Sunday, 06-Nov-94 08:49:37 GMT ; RFC-850, объявлено устаревшим в RFC-1036

    Sun Nov 6 08:49:37 1994 ; ANSI C's ASCtime() format

    Первый формат предпочтительнее, как стандарт Интернет и представляет собой форму фиксированной длины, определенную RFC-1123. Второй формат используется достаточно широко, но базируется на устаревшем документе RFC-850 [12], формат даты не имеет 4 цифр года. Клиенты и серверы HTTP/1.1, которые анализируют дату, должны уметь работать со всеми тремя форматами (для совместимости с HTTP/1.0), хотя они должны сами генерировать время/дату согласно формату RFC-1123.

    Замечание: Получатели значений даты должны быть готовы принять коды, которые посланы не приложениями HTTP, что случается, когда данные поступают через прокси/порты или по почте в SMTP- или NNTP-форматах.

    Все марки времени/даты HTTP должны соответствовать времени по Гринвичу (GMT). Это указано в первых двух форматах путем включения строки "GMT" и должно предполагаться во всех прочих случаях.

    HTTP-date = RFC-1123-date | rRFC-850-date | asctime-date
    RFC-1123-date = wkday "," SP date1 SP time SP "GMT"
    RFC-850-date = weekday "," SP date2 SP time SP "GMT"
    asctime-date = wkday SP date3 SP time SP 4DIGIT
    date1 = 2DIGIT SP month SP 4DIGIT ; day month year (e.g., 02 Jun 1982)
    date2 = 2DIGIT "-" month "-" 2DIGIT ; day-month-year (e.g., 02-Jun-82)
    date3 = month SP ( 2DIGIT | ( SP 1DIGIT )) ; month day (e.g., Jun 2)
    time = 2DIGIT ":" 2DIGIT ":" 2DIGIT ; 00:00:00 - 23:59:59
    wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"
    weekday = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday"
    month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
    <


    /p> Замечание: HTTP требования для формата метки даты/времени применимы только для использования в рамках реализации самого протокола. Клиенты и сервера не требуют применения этих форматов для пользовательских презентаций, протоколирования запросов и т.д..

    2.3.2. Интервалы времени в секундах

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

    delta-seconds = 1*DIGIT

    2.4. Наборы символов

    HTTP использует то же определение термина "набор символов", что дано для MIME:

    Термин "набор символов", используемый в данном документе, относится к методу, который с помощью одной или более таблиц преобразует последовательность октетов в последовательность символов. Заметьте, что не требуется безусловное обратное преобразование, при этом не все символы могут быть доступны и одному и тому же символу может соответствовать более чем одна последовательность октетов. Это определение имеет целью допустить различные виды кодировок символов, от простых однотабличных, таких как US-ASCII, до сложных - таблично переключаемых методов, используемых, например, в ISO 2022. Однако, определение, связанное с набором символов MIME, должно полностью специфицировать схему соответствия октетов и символов. Использование внешних профайлов для определения схемы шифрования не допустимо.

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

    Наборы символов HTTP идентифицируются лексемами, которые не чувствительны к использованию строчных или прописных букв. Полный набор лексем определен регистром наборов символов IANA [19].

    charset = token

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


    Приложение должно ограничить использование символьных наборов только теми, которые определены регистром IANA.

    2.5. Кодировки содержимого

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

    content-coding = token

    Все значения кодировок содержимого не зависят от того, используются строчные или прописные символы. HTTP/1.1 использует значения кодировок содержимого в полях заголовка Accept-Encoding (раздел 13.3) и Content-Encoding (раздел 13.12). Хотя значение описывает кодирование содержимого, более важным является то, что оно определяет механизм декодирования.

    Комитет по стандартным числам Интернет IANA (Internet Assigned Numbers Authority) выполняет функции регистра для значений лексем кодирования содержимого, этот регистр хранит следующие лексемы:

    gzip

    Формат кодирования, реализуемый программой архивации файлов "gzip" (GNU zip), как описано в RFC 1952 [25]. Этот формат соответствует кодированию Lempel-Ziv (LZ77) с 32 битным CRC.

    compress

    Формат кодирования, реализуемый стандартной программой UNIX для архивации файлов "compress". Этот формат соответствует адаптивному методу кодирования Lempel-Ziv-Welch (LZW).

    Замечание: Использование имен программ для идентификации форматов кодирования не является желательным и будет в будущем заменено. Их использование здесь является следствием исторической практики. Для совместимости с предшествующими реализациями HTTP, приложения должны считать "x-gzip" и "x-compress" эквивалентными "gzip" и "compress" соответственно.

    deflate

    Формат "zlib" определен документом RFC 1950 [31] в комбинации с механизмом сжатия "deflate", описанным в RFC 1951 [29].



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

    2.6. Транспортное кодирование

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

    Transfer-coding = "chunked" | transfer-extension
    Transfer-extension = token
    Все значения транспортного кодирования не зависят от того, строчные или прописные буквы здесь использованы. HTTP/1.1 несет значения транспортного кодирования в поле заголовка Transfer-Encoding (раздел 13.40).

    Транспортные кодировки аналогичны используемым значениям Content-Transfer-Encoding MIME, которые были введены для обеспечения безопасной передачи двоичных данных через 7-битную транспортную среду. Однако безопасная транспортировка имеет другие аспекты в рамках 8-битного протокола передачи сообщений. В HTTP, единственной небезопасной характеристикой тела сообщения является неопределенность его длины (раздел 6.2.2), или желание зашифровать данные при передаче по общему каналу.

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

    Chunked Body = *chunk "0" CRLF footer CRLF
    Chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF
    Hex-no-zero =
    Chunk-size = hex-no-zero *HEX
    Chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
    Chunk-ext-name = token
    Chunk-ext-val = token | quoted-string
    Chunk-data = chunk-size(OCTET)
    footer = *entity-header
    <


    /p> Блочное кодирование фрагментов завершается пакетом нулевой длины, за которыми следует завершающая запись и пустая строка. Назначение завершающей записи заключается в том, чтобы дать информацию о динамически сформированном объекте; приложения не должны пересылать поля заголовка в завершающей записи, кроме тех, которые специально оговорены, например, такие как Content-MD5 или будущие расширения HTTP для цифровой подписи. Пример процесса такого кодирования представлен в приложении 16.4.6.

    Все приложения HTTP/1.1 должны быть способны получать и декодировать получаемые фрагменты ("chunked"-кодирование), и должны игнорировать расширения транспортного кодирования, которые они не понимают. Сервер, получающий тело объекта с транспортной кодировкой, которую он не понимает, должен отослать отклик c кодом 501 (Unimplemented – не применимо), и закрыть соединение. Сервер не должен использовать транспортное кодирование при посылке данных клиенту HTTP/1.0.

    2.7. Типы среды

    HTTP использует типы среды Интернет (Internet Media Types) в полях заголовка Content-Type (раздел 13.18) и Accept (раздел 13.1) для того, чтобы обеспечить широкий и открытый обмен с самыми разными типа среды.

    Media-type = type "/" subtype *( ";" parameter )
    type = token
    subtype = token
    Параметры могут следовать за type/subtype в форме пар атрибут/значение.

    Parameter = attribute "=" value
    attribute = token
    value = token | quoted-string
    Имена типа, субтипа и атрибутов параметра могут набираться, как строчными, так и прописными буквами. Значения параметров могут быть и чувствительны к используемому регистру, в зависимости от семантики и имени параметра. Строчный пробел (LWS) не должен использоваться ни между типом и субтипом, ни между атрибутом и значением. Агенты пользователя, которые распознают тип среды, должны обрабатывать (или обеспечить обработку с использованием внешнего приложения для работы агента пользователя с типом/субтипом) параметры для типа MIME так, как это описано для данного типа/субтипа, и информировать пользователя о любых возникающих проблемах.



    Замечание. Некоторые старые приложения HTTP не узнают параметры типа среды. При посылке данных старому HTTP-приложению, программы должны использовать параметры типа среды, только когда они необходимы по описанию типа/субтипа. Значения типа среды регистрируются IANA (Internet Assigned Number Authority). Процесс регистрации типа среды описан в RFC 2048 [17]. Использование незарегистрированных типов среды настоятельно не рекомендуется.

    2.7.1. Канонизация и текст по умолчанию

    Типы среды Интернет регистрируются каноническим образом. Вообще, тело объекта, передаваемого с помощью HTTP сообщений, должно быть представлено соответствующим каноническим способом, прежде чем будет послано, исключение составляет тип "text", как это описано в следующем параграфе.

    В случае канонической формы субтип среды "text" использует CRLF для завершения строки текста. HTTP ослабляет это требование и позволяет передавать текст, используя просто CR или LF, представляющие разрыв строки. HTTP приложения должны воспринимать CRLF, “голое” CR и LF как завершение строки для текстовой среды полученной через HTTP. Кроме того, если текст представлен в символьном наборе, где нет октетов 13 и 10 для CR и LF соответственно, как это имеет место в случае мультибайтных символьных наборов, HTTP позволяет использовать соответствующие символьные представления для CR и LF. Эта гибкость в отношении разрыва строк относится только к текстовой среде в теле объекта; CR или LF не должны подставляться вместо CRLF в любые управляющие структуры HTTP (такие как поля заголовка).

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

    Параметр "charset" используется с некоторыми типами среды, чтобы определить символьный набор (раздел 2.4). Когда параметр charset не задан отправителем явно, субтип среды "text" определяется так, что используется символьный набор по умолчанию "ISO-8859-1".


    Данные с набором символов, отличным от "ISO-8859-1" или его субнабора, должны помечаться соответствующим значением charset.

    Некоторые программы HTTP/1.0 интерпретируют заголовок Content-Type без параметра charset, неправильно предполагая, что "получатель должен решить сам, какой это набор". Отправители, желающие заблокировать такое поведение, могут включать параметр charset, даже когда charset равен ISO-8859-1 и должны делать так, когда известно, что это не запутает получателя.

    К сожалению, некоторые старые HTTP/1.0 клиенты не обрабатывают корректно параметр charset. HTTP/1.1 получатели должны учитывать метку charset, присланную отправителем, и те агенты пользователя, которые умеют делать предположение относительно символьного набора, должны использовать символьный набор из поля content-type, если они поддерживают этот набор, а не набор, предпочитаемый получателем.

    2.7.2. Составные типы

    MIME обеспечивает нескольких составных типов – инкапсуляция одного или более объектов в общее тело сообщения. Все составные типы имеют общий синтаксис, как это определено в MIME [7], и должны включать граничный параметр, являющийся частью значения типа среды. Тело сообщения является само протокольным элементом и, следовательно, должно использовать только CRLF для обозначения разрывов строки. В отличии от MIME, завершающая часть любого составного cообщения должна быть пустой. HTTP приложения не должны передавать завершающую часть (даже если исходное составное сообщение содержит такую завершающую часть (эпилог-подпись).

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

    Вообще, рекомендуется, чтобы агент пользователя HTTP имел идентичное или схожее поведение с агентом пользователя MIME при получении составного типа. Если приложение получает неузнаваемый составной субтип, оно должно обрабатывать его также как "multipart/mixed".



    Замечание: Тип "multipart/form-data" специально определен для переноса данных совместимого с методом обработки почтовых запросов, как это описано в RFC 1867 [15].

    2.8. Лексемы (token) продукта

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

    Product = token ["/" product-version]
    Product-version = token
    Примеры:

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

    Server: Apache/0.8.4

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

    2.9. Значения качества (Quality values)

    HTTP согласование параметров содержимого (раздел 12) использует короткие числа с плавающей запятой для указания относительной важности (веса) различных согласуемых параметров. Вес нормализуется на истинное число в диапазоне 0 - 1, где 0 равен минимальному, а 1 максимальному значению. Приложения HTTP/1.1 не должны генерировать более трех чисел после запятой. Рекомендуется, чтобы конфигурация пользователя для этих значений удовлетворяла тем же ограничениям.

    qvalue = ( "0" [ "." 0*3DIGIT ] ) | ( "1" [ "." 0*3("0") ] )

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

    2.10. Языковые метки

    Языковая метка идентифицирует естественный язык.


    Компьютерные языки в этот перечень не входят. HTTP использует языковые метки в полях Accept-Language и Content-Language.

    Синтаксис и регистр языковых меток HTTP тот же, что и определенный в RFC 1766 [1]. Языковая метка содержит одну или более частей: первичная языковая метка и последовательность субметок, которая может и отсутствовать:

    language-tag = primary-tag *( "-" sub-tag )
    primary-tag = 1*8ALPHA
    sub-tag = 1*8ALPHA
    Пробел не допустим в метке, применение строчных и прописных букв не играет никакой роли. Перечень языковых меток контролируется IANA. Ниже приведены примеры языковых меток:

    en, en-US, en-cockney, i-cherokee, x-pig-latin

    где любые две буквы первичной метки представляют собой языковую аббревиатуру ISO 639 и две буквы исходной субметки соответствуют коду страны ISO 3166 (последние три метки не являются зарегистрированными; все кроме последней могут быть зарегистрированы в будущем).

    2.11. Метки объектов

    Метки объектов служат для сравнения двух или более объектов из одного и того же запрошенного ресурса. HTTP/1.1 использует метки объектов в полях заголовков ETag (раздел 13.20), If-Match (раздел 13.25), If-None-Match (раздел 13.26) и If-Range (раздел 13.27). Метки объекта состоят из строк, заключенных в кавычки, перед ней может размещаться индикатор слабости.

    entity-tag = [ weak ] opaque-tag
    Weak = "W/"
    opaque-tag = quoted-string
    "Сильная метка объекта" (strong entity tag) может принадлежать двум объектам ресурса, если они эквивалентны на октетном уровне.

    "Слабая метка объекта " (weak entity tag) отмечается префиксом "W/", может относиться к двум объектам ресурса, только если объекты эквивалентны и могут быть взаимозаменяемы. Слабая метка объекта может использоваться для "слабого" сравнения.

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



    2.12. Структурные единицы

    HTTP/1. 1 позволяет клиенту запросить только часть объекта (диапазон). HTTP/1.1 использует структурные единицы, определяющие выделение части объекта, в полях заголовка Range (раздел 13.36) и Content-Range (раздел 13.17). Объект может быть разбит на фрагменты с использованием различных структурных единиц.

    range-unit = bytesunit | other-range-unit
    bytes-unit = "bytes"
    other-range-unit = token
    Единственной структурной единицей, определенной в HTTP/1.1, является "bytes". HTTP/1.1 реализации могут игнорировать диапазоны, специфицированные с использованием других структурных единиц. HTTP/1.1 сконструирован так, чтобы позволить реализацию приложений, которые не зависят от знания диапазонов.

    4.5.6.1.3. HTTP сообщение

    3.1. Типы сообщений

    Сообщения HTTP включают в себя запросы клиента к серверу и отклики сервера клиенту.

    HTTP-message = Request | Response ; HTTP/1.1 messages

    Сообщения запрос (раздел 5) и отклик (раздел 6) используют общий формат сообщений RFC-822 [9] для передачи объектов (поле данных сообщения). Оба типа сообщений состоят из стартовой строки, одного или более полей заголовка (также известные как "заголовки"), пустой строки (то есть, строка, содержащая CRLF), отмечающей конец полей заголовка, а также опционного тела сообщения.

    generic-message = start-line

    *message-header

    CRLF

    [ message-body ]

    start-line = Request-Line | Status-Line

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

    Замечание: Определенные не корректные реализации HTTP/1.0 клиентов генерируют дополнительные CRLF после запроса POST. Клиент HTTP/1.1 не должен посылать CRLF до или после запроса.

    3.2. Заголовки сообщений

    Поля заголовка HTTP, которые включают в себя поля общего заголовка (раздел 3.5), заголовка запроса (раздел 4.3), заголовка отклика (раздел 6.2), и заголовка объекта (раздел 6.1), следуют тому же общему формату, что дан в разделе 3.1 RFC 822 [9].


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

    Message-header = field-name ":" [ field-value ] CRLF
    field-name = token
    field-value = *( field-content | LWS )
    field-content = < OCTET’ы образуют значения поля и состоят из *TEXT или комбинаций лексем, tspecials и закавыченных строк >

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

    Множественные поля заголовка сообщения с идентичными именами могут присутствовать тогда и только тогда, когда значение поля определяется как список из элементов, разделенных запятыми [то есть, #(значения)]. Должна быть предусмотрена возможность объединять множественные поля заголовка в одну пару "имя_поля: значение_поля", без изменения семантики сообщения, путем добавления каждой последующей пары поле-значение, отделенных друг от друга запятыми. Порядок, в котором следуют поля заголовка с идентичными именами, влияет на последующую интерпретацию значения комбинированного поля, по этой причине прокси-сервер не должен менять порядок значений этих полей при переадресации сообщения.

    3.3. Тело сообщения

    Тело сообщения HTTP (если имеется) используется для переноса тела объекта, сопряженного с запросом или откликом. Тело сообщения отличается от тела объекта, только когда используется транспортное кодирование, как это указано в поле заголовка Transfer-Encoding (раздел 13.40).



    message-body = entity-body

    |

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

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

    Для сообщений-откликов включение в них тела сообщения зависит от метода запроса и статусного кода отклика (раздел 5.1.1). Все отклики в случае метода запроса HEAD не должны включать тела сообщения, даже если присутствуют поля заголовка объекта, позволяющие предположить его присутствие. Все отклики 1xx (информационные), 204 (никакого содержимого) и 304 (не модифицировано) не должны включать тела сообщения. Все другие отклики включают в себя тело сообщения, хотя оно может иметь и нулевую длину.

    3.4. Длина сообщения

    Когда тело включено в сообщение, его длина определяется следующим образом (в порядке приоритета):



    1. Любое сообщение-отклик, которое не должно включать в себя тело сообщения (такое как отклик 1xx, 204 и 304, а также любые отклики на запрос HEAD) всегда завершаются первой пустой строкой после полей заголовка, вне зависимости от присутствующих в сообщении полей заголовка объекта.


    2. Если присутствует поле заголовка Transfer-Encoding (раздел 13.40) и указано, что использовано по фрагментное ("chunked") транспортное кодирование, тогда длина тела определяется выбранной схемой кодирования (раздел 2.6).


    3. Если присутствует поле заголовка Content-Length (раздел 13.14), его значение в байтах и определяет длину тела сообщения.

      Если сообщение использует тип cреды "multipart/byteranges", который является самоограничивающим, тогда он и определяет длину.


      Этот тип среды не должен использоваться, если отправитель не знает, может ли получатель разобрать его. Присутствие в запросе заголовка Range с множественными спецификаторами диапазона подразумевает, что клиент может разобрать отклики типа multipart/byteranges.

      Определяется сервером при закрытии связи. (Закрытие соединения не может использоваться для обозначения конца тела запроса, так как это не оставит возможности для сервера послать отклик.)



    Для совместимости с приложениями HTTP/1.0, запросы HTTP/1.1, содержащие тело запроса, должны включать корректное поле заголовка Content-Length. Если запрос содержит тело сообщения, а поле Content-Length отсутствует, рекомендуется, чтобы сервер реагировал откликом 400 (плохой запрос), если он не может определить длину сообщения, или 411 (необходима длина), если он настаивает на получении корректного поля Content-Length.

    Все приложения HTTP/1.1, которые получают объект (entity) должны понимать блочное ("chunked") транспортное кодирование (раздел 2.6), таким образом, разрешая использование этого механизма для сообщений, когда длина сообщения не может быть определена заранее.

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

    Когда в сообщении присутствует поле Content-Length и разрешено наличие тела сообщения, его значение поля должно строго соответствовать числу октетов в теле сообщения. Агенты пользователя HTTP/1.1 должны оповещать пользователя, если получено сообщение некорректной длины.

    3.5. Общие поля заголовка

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

    general-header = Cache-Control ; Раздел 13.9
      | Connection ; Раздел 13.10
      | Date ; Раздел 13.19
      | Pragma ; Раздел 13.32
      | Transfer-Encoding ; Раздел 13.40
      | Upgrade ; Раздел 13.41
      | Via ; Раздел 13.44
    <


    /p> Имена полей общего заголовка могут быть расширены только при изменении версии протокола. Однако, новые или экспериментальные поля заголовка могут использоваться при условии, если партнеры обмена способны их распознавать, как поля общего заголовка. Не узнанные поля заголовка считаются полями заголовка объекта (entity).

    4.5.6.1.4. Запрос

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

    Request = Request-Line
    *( generalheader
    | requestheader
    | entityheader )
    CRLF
    [ messagebody ]
    4.1. Строка запроса

    Строка запроса начинается с лексемы метода, за которой следует Request-URI, версия протокола, завершается строка последовательностью CRLF. Элементы разделяются символами SP. Символы CR или LF запрещены кроме завершающей последовательности CRLF.

    Request Line = Method SP Request-URI SP HTTP-Version CRLF
    4.1.1. Метод

    Лексема Method указывает на метод, который должен быть применен к ресурсу, обозначенному Request-URI. При записи метода использование строчных или прописных букв не безразлично.

    Method = "OPTIONS" ; Раздел 9.2
      | "GET" ; Раздел 9.3
      | "HEAD" ; Раздел 9.4
      | "POST" ; Раздел 9.5
      | "PUT" ; Раздел 9.6
      | "DELETE" ; Раздел 9.7
      | "TRACE" ; Раздел 9.8
      | extension-method

    extension-method = token
    Список методов допустимых для ресурса может быть специфицирован полем заголовка Allow (раздел 13.7). Возвращаемый код отклика всегда оповещает клиента, допустим ли метод для ресурса, так как набор допустимых методов может меняться динамически. Серверам рекомендуется возвращать статусный код 405 (Метод не допустим), если метод известен серверу, но не приемлем для запрашиваемого ресурса и 501 (Не применим), если метод не узнан или не приемлем для сервера. Список методов, известных серверу может быть представлен в поле заголовка отклика Public (раздел 13.35).



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

    5.1.2 URI запроса

    URI запроса является универсальным идентификатором ресурса (раздел 2.2) и идентифицирует ресурс, который запрашивается.

    Request-URI = "*" | absoluteURI | abs_path

    Три опции для Request-URI зависят от природы запроса. Звездочка "*" означает, что запрос приложим не к заданному ресурсу, но к самому серверу, и допустим только, когда используемый метод не обязательно приложим к ресурсу. Примером может служить

    OPTIONS * HTTP/1.1

    Форма абсолютного URI необходима, когда запрос адресован к прокси-серверу. Прокси-серверу посылается запрос переадресации с целью получения отклика. Заметьте, что прокси может переадресовать запрос другому прокси или серверу, указанному абсолютным URI. Для того, чтобы избежать петель запросов прокси-сервер должен быть способен распознавать все имена серверов, включая любые псевдонимы, локальные вариации и численные IP-адреса. Пример строки запроса представлен ниже:

    GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

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

    Наиболее общей формой Request-URI является та, которая используется для идентификации ресурса на исходном сервере или внешнем порту сети. В этом случае абсолютный проход к URI должен быть занесен в abs_path (см. раздел 2.2.1) как Request-URI, а сетевой адрес URI (net_loc) должен быть занесен в поле заголовка Host. Например, клиент, желающий извлечь ресурс из выше приведенного примера непосредственно с базового сервера, установит TCP-соединение через порт 80 с ЭВМ "www.w3.org" и пошлет строки:

    GET /pub/WWW/TheProject.html HTTP/1.1

    Host: www.w3.org

    за которыми следует остальная часть запроса.


    Заметьте, что абсолютный проход не может быть пустым; если его нет в исходном URI, он должен быть задан в виде "/" (корневой каталог сервера).

    Если прокси получает запрос без какого-либо прохода в Request-URI, а метод, специфицирован так, чтобы быть способным поддерживать форму “*” запросов, тогда последний прокси в цепочке запроса должен переадресовать запрос с "*" в качестве финального Request-URI. Например, запрос

    OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1

    будет переадресован прокси как

    OPTIONS * HTTP/1.1

    Host: www.ics.uci.edu:8001

    после подключения к порту 8001 ЭВМ "www.ics.uci.edu".

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

    В запросах, которые они переадресуют, прокси-серверы не должны переписывать "abs_path" часть Request-URI каким-либо способом, за исключением случая, описанного выше, когда нулевой abs_path заменяется на "*".

    Замечание: Правило "no rewrite" препятствует прокси изменить смысл запроса, когда исходный сервер некорректно использует незарезервированный URL символ для зарезервированных целей. Следует остерегаться того, что некоторые предшествующие варианты прокси-серверов HTTP/1.1 допускали перезапись Request-URI.

    4.2. Ресурс, идентифицируемый запросом

    Исходному серверу HTTP/1.1 рекомендуется заботиться о точном определении ресурса, идентифицированного Интернет-запросом путем анализа Request-URI и поля заголовка Host.

    Исходный сервер, который не разделяет ресурсы по запрашиваемого ЭВМ, может игнорировать значение поля заголовка Host. (См. раздел 16.5.1 по поводу других требований по поддержке Host в HTTP/1.1.)

    Исходный сервер, который различает ресурсы с использованием имени ЭВМ, должен использовать следующие правила для определения ресурса в запросе HTTP/1.1:



    1. Если Request- URI является absoluteURI, ЭВМ определена частью Request-URI. Любое значение поля заголовка Host в запросе должно игнорироваться.


    2. Если Request-URI не является absoluteURI, а запрос содержит поле заголовка Host, ЭВМ определяется значением поля заголовка Host.


    3. Если ЭВМ, так как это определено правилами 1 или 2, не является ЭВМ сервера, откликом должно быть сообщение об ошибке с кодом 400 (Плохой запрос - Bad Request).


    Получатели HTTP/1.0-запроса, где отсутствует поле заголовка Host, могут попытаться использовать эвристику (напр., рассмотрение прохода URI на предмет уникальной конкретной ЭВМ) для того, чтобы определить, какой конкретный ресурс запрошен.

    4.3. Поля заголовка запроса

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

    Request-header = Accept ; Раздел 13.1
      | Accept-Charset ; Раздел 13.2
      | Accept-Encoding ; Раздел 13.3
      | Accept-Language ; Раздел 13.4
      | Authorization ; Раздел 13.8
      | From ; Раздел 13.22
      | Host ; Раздел 13.23
      | If-Modified-Since ; Раздел 13.24
      | If-Match ; Раздел 13.25
      | If-None-Match ; Раздел 13.26
      | If-Range ; Раздел 13.27
      | If-Unmodified-Since ; Раздел 13.28
      | Max-Forwards ; Раздел 13.31
      | Proxy-Authorization ; Раздел 13.34
      | Range ; Раздел 13.36
      | Referer ; Раздел 13.37
      | User-Agent ; Раздел 13.42
    Поля имен заголовка запроса могут быть безопасно расширены в сочетании с изменением версии протокола. Однако новым или экспериментальным полям может быть придана семантика полей заголовка запроса, если все участники обмена способны их распознать. Не узнанные поля заголовка рассматриваются как поля заголовка объекта.

    4.5.6.1.5. Отклик

    После получения и интерпретации сообщения-запроса, сервер реагирует, посылая HTTP сообщение отклик.



    Response = Status-Line ; Раздел 5.1
      *( general-header ; Раздел 3.5
      | response-header ; Раздел 5.2
      | entity-header ) ; Раздел 6.1
      CRLF  
      [ message-body ] ; Раздел 6.2
    5.1. Статусная строка

    Первая строка сообщения- отклика является статусной строкой, состоящей из кода версии протокола, за которым следует числовой статусный код и его текстовое представление, все элементы разделяются символами SP (пробел). Никакие CR или LF не допустимы, за исключением завершающей последовательности CRLF.

    Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

    5.1.1. Статусный код и словесный комментарий

    Элемент Status-Code представляет собой 3-значный цифровой результирующий код попытки понять и исполнить запрос. Эти коды полностью определены в разделе 9. Словесный комментарий (Reason-Phrase) предназначен для того, чтобы дать краткое описание статусного кода. Статусный код служит для использования автоматами, а словесный комментарий для пользователей. Клиент не обязан рассматривать или отображать словесный комментарий.

    Первая цифра статусного кода определяет класс отклика. Последние две цифры не имеют четко определенной функции. Существует 5 значений первой цифры:

  • 1xx: Информационный – Запрос получен, процесс продолжается


  • 2xx: Успех (Success) – Запрос успешно получен, понят и воспринят


  • 3xx: Переадресация (Redirection) – Нужны дополнительные действия для завершения выполнения запроса


  • 4xx: Ошибка клиента (Client Error) – Запрос содержит синтаксическую ошибку или не может быть выполнен


  • 5xx: Ошибка сервера (Server Error) – Сервер не смог выполнить корректный запрос


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

    Status-Code = "100" ; Continue
      | "101" ; Switching Protocols
      | "200" ; OK
      | "201" ; Created
      | "202" ; Accepted
      | "203" ; Non-Authoritative Information
      | "204" ; No Content
      | "205" ; Reset Content
      | "206" ; Partial Content
      | "300" ; Multiple Choices
      | "301" ; Moved Permanently
      | "302" ; Moved Temporarily
      | "303" ; See Other
      | "304" ; Not Modified
      | "305" ; Use Proxy
      | "400" ; Bad Request
      | "401" ; Unauthorized
      | "402" ; Payment Required
      | "403" ; Forbidden
      | "404" ; Not Found
      | "405" ; Method Not Allowed
      | "406" ; Not Acceptable
      | "407" ; Proxy Authentication Required
      | "408" ; Request Time-out
      | "409" ; Conflict
      | "410" ; Gone
      | "411" ; Length Required
      | "412" ; Precondition Failed
      | "413" ; Request Entity Too Large
      | "414" ; Request-URI Too Large
      | "415" ; Unsupported Media Type
      | "500" ; Internal Server Error
      | "501" ; Not Implemented
      | "502" ; Bad Gateway
      | "503" ; Service Unavailable
      | "504" ; Gateway Time-out
      | "505" ; HTTP Version not supported
      | extension-code
    <


    /p>
    Extension-code = 3DIGIT
    Reason-Phrase = *
    Статусные коды HTTP допускают расширение. HTTP приложения могут не понимать значение всех зарегистрированных статусных кодов, хотя их понимание, очевидно, является желательным. Однако, приложения должны понимать класс любого статусного кода, который задается его первой цифрой, и воспринимать не узнанный отклик как x00. Не узнанный статусный отклик не должен заноситься в буфер. Например, если клиентом получен не распознаваемый статусный код 431, он может предположить, что произошло что-то с запросом и рассматривать отклик так, как если бы он равнялся 400. В таких случаях агентам пользователя рекомендуется предоставлять пользователю объект с откликом, который содержит текст, поясняющий причину создавшейся ситуации.

    5.2 Поля заголовка отклика

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

    Response-header = Age ; Раздел 13.6
      | Location ; Раздел 13.30
      | Proxy-Authenticate ; Раздел 13.33
      | Public ; Раздел 13.35
      | Retry-After ; Раздел 13.38
      | Server ; Раздел 13.39
      | Vary ; Раздел 13.43
      | Warning ; Раздел 13.45
      | WWW-Authenticate ; Раздел 13.46
    Имена полей заголовка отклика могут быть расширены только в случае изменения версии протокола. Однако новые или экспериментальные поля могут быть введены с учетом семантики полей заголовка отклика, если все участники обмена способны распознавать эти поля. Не узнанные поля заголовка рассматриваются, как поля заголовка объекта (entity-header fields).

    4.5.6.1.6. Объект (Entity)

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

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



    6.1. Поля заголовка объекта

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

    Entity-header = Allow ; Раздел 13.7
      | Content-Base ; Раздел 13.11
    Entity-header | Content- ; Раздел 13.12
    Entity-header | Content-Language ; Раздел 13.13
    Entity-header | Content-Length ; Раздел 13.14
    Entity-header | Content-Location ; Раздел 13.15
    Entity-header | Content-MD5 ; Раздел 13.16
    Entity-header | Content-Range ; Раздел 13.17
    Entity-header | Content-Type ; Раздел 13.18
    Entity-header | Etag ; Раздел 13.20
    Entity-header | Expires ; Раздел 13.21
    Entity-header | Last-Modified ; Раздел 13.29
    Entity-header | extension-header
    extension-header = message-header

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

    6.2. Тело объекта

    Тела объекта (если они имеются), пересылаемые HTTP-запросом или откликом, имеют формат и кодировку, определенную полями заголовка объекта.

    entity-body = *OCTET
    Тело объекта присутствует в сообщении только когда имеется тело сообщения, как это описано в разделе 3.3. Тело объекта получается из тела сообщения путем декодирования любого транспортного кода (Transfer-Encoding), который может быть применен для обеспечения безопасной и корректной доставки.

    6.2.1. Тип

    Когда тело объекта включено в сообщение, тип данных этого тела определяется полями заголовка Content-Type и Content-Encoding. Они определяют два слоя, заданных моделью кодирования:

    entity-body := Content-Encoding( Content-Type( данные ) )

    Content-Type специфицирует тип среды данных.

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


    По умолчанию никакого кодирования не используется.

    Любое HTTP/1.1 сообщение, содержащее тело объекта, должно включать поле заголовка Content-Type, определяющее тип среды для данного тела. Только в случае, когда тип среды не задан полем Content-Type, получатель может попытаться предположить, каким является тип среды, просмотрев содержимое и/или расширения имен URL, использованного для идентификации ресурса. Если тип среды остается неизвестным, получателю следует рассматривать его как "application/octet-stream" (поток октетов).

    6.2.2. Длина

    Длина тела объекта равна длине тела сообщения, после того как произведено транспортное декодирование. Раздел 4.4 определяет то, как определяется длина тела сообщения.

    4.5.6.1.7. Соединения

    7.1. Постоянные соединения

    7.1.1. Цель

    Прежде чем установить постоянную связь должно быть реализовано отдельное TCP соединение с тем, чтобы получить URL. Это увеличивает нагрузку HTTP серверов и вызывает перегрузку каналов Интернет. Использование изображений и другой связанной с этим информации часто требует от клиента множественных запросов, направленных определенным серверам за достаточно короткое время. Анализ этих проблем содержится в [30][27], а результаты макетирования представлены в [26].

    Постоянное HTTP соединение имеет много преимуществ:

  • При открытии и закрытии TCP соединений можно сэкономить время CPU и память, занимаемую управляющими блоками протокола TCP.


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


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


  • HTTP может функционировать более эффективно, так как сообщения об ошибках могут доставляться без потери TCP связи.


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


  • 7.1.2. Общие процедуры

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

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

    7.1.2.1. Согласование

    HTTP/1.1 сервер может предполагать, что HTTP/1.1 клиент намерен поддерживать постоянное соединение, если только в поле заголовка Connection не записана лексема "close". Если сервер принял решение закрыть связь немедленно после посылки отклика, ему рекомендуется послать заголовок Connection, включающий лексему связи close.

    Клиент HTTP/1.1 может ожидать, что соединение останется открытым, но примет решение оставлять ли его открытым на основе того, содержит ли отклик сервера заголовок Connection с лексемой close.

    Если клиент или сервер посылает лексему close в заголовке Connection, этот запрос становится последним для данного соединения.

    Клиентам и серверам не следует предполагать, что соединение будет оставаться постоянным для версий HTTP, меньше 1.1, если только не получено соответствующее уведомление.

    7.1.2.2. Буферизация

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

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


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

    7.1.3. Прокси-серверы

    Особенно важно то, чтобы прокси-серверы корректно использовали свойства поля заголовка Connection, как это специфицировано в 13.2.1.

    Прокси-сервер должен сигнализировать о постоянном соединении отдельно своему клиенту и исходному серверу (origin server) или другому прокси, с которым связан. Каждое постоянное соединение устанавливается только для одной транспортной связи.

    Прокси-сервер не должен устанавливать постоянное соединение с HTTP/1.0 клиентом.

    7.1.4. Практические соображения

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

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

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

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


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

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

    Клиенты, которые используют постоянные соединения, должны ограничивать число одновременных связей, которые они поддерживают с конкретным сервером. Однопользовательскому клиенту рекомендуется поддерживать не более двух соединений с любым сервером или прокси. Прокси следует использовать до 2*N соединений с другим сервером или прокси, где N равно числу активных пользователей. Эти рекомендации призваны улучшить время отклика HTTP и исключить перегрузки Интернет и других сетей.

    7.2. Требования к передаче сообщений

    Общие требования:

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


  • Клиент HTTP/1.1 (или позднее), посылая тело сообщения, должен мониторировать сетевое соединение на наличие сигнала ошибки. Если клиент обнаружил состояние ошибки, он должен немедленно прервать передачу. Если тело передается с использованием блочной кодировки ("chunked" encoding, раздел 2.6), возможно применение фрагмента нулевой длины и пустой завершающей секции для обозначения преждевременного конца сообщения. Если телу предшествовал заголовок Content-Length, клиент должен разорвать соединение.


  • Клиент HTTP/1.1 (или позднее) должен быть готов принять код статуса 100 (Continue - продолжить), за которым следует обычный отклик.




  • Сервер HTTP/1.1 (или позднее), который получает запрос от клиента HTTP/1.0 (или ранее), не должен передавать отклик 100 (continue - продолжение), ему следует или ждать нормального завершения запроса (таким образом, избегая его прерывания) или преждевременно разрывать соединение.


  • Клиентам следует запомнить номер версии, по крайней мере, сервера, с которым проводилась работа последним, если клиент HTTP/1.1 получил отклик от сервера HTTP/1.1 (или позднее) и обнаружил разрыв соединения до получения какого-либо статусного кода, клиенту следует повторно попытаться направить запрос без участия пользователя (см. раздел 9.1.2). Если клиент действительно повторяет запрос, то клиент:

  • Должен сначала послать поля заголовка запроса, а затем


  • Должен ждать, того, что сервер пришлет отклик 100 (Continue), тогда клиент продолжит работу, или код статуса, сигнализирующего об ошибке.


  • Если клиент HTTP/1.1 не получил отклика от сервера HTTP/1.1 (или более поздней версии), ему следует считать, что сервер поддерживает версию HTTP/1.0 или более раннюю и не использует отклик 100 (Continue). Если в этом случае клиент обнаруживает закрытие соединения до получения какого-либо статусного кода от сервера, клиенту следует повторить запрос. Если клиент повторил запрос серверу HTTP/1.0, ему следует использовать следующий алгоритм получения надежного отклика:

  • Инициировать новое соединение с сервером


  • Передать заголовок запроса


  • Инициализировать переменную R для оценки задержки отклика сервера (round-trip time) (напр., на основе времени установления соединения), если RTT не доступно, ему присваивается значение 5 секунд.


  • Вычислить T = R * (2**N), где N равно числу предыдущих попыток запроса.


  • Ждать в течение Т секунд или до прихода статуса ошибки (что наступит раньше)


  • Если не получен сигнал ошибки, после T секунд передается тело запроса.


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




  • Вне зависимости от версии сервера, если получен статус ошибки, то клиент

  • Не должен продолжать операции и


  • Должен прервать соединение, если процедура не завершена посылкой сообщения.


  • Клиент HTTP/1.1 (или позднее), который обнаруживает разрыв соединения после получения флага 100 (Continue), но до получения какого-либо статусного кода, должен повторить запрос и не должен ждать отклика 100 (Continue), но может и делать это, если это упрощает реализацию программы.

    4.5.6.1.8. Метод определений

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

    8.1. Безопасные и Idempotent методы

    8.1.1. Безопасные методы


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

    В частности, установлено соглашение, что методы GET и HEAD никогда не должны выполнять какие либо функции помимо доставки информации. Эти методы должны рассматриваться как вполне безопасные. Это позволяет агентам пользователя представлять другие методы, такие как POST, PUT и DELETE, особым способом, так что пользователь сам будет заботиться о возможности опасных операций, которые могут быть выполнены в результате реализации запроса.

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

    8.1.2. Подобные методы

    Методы могут также иметь свойство "idempotence", при котором (помимо ошибок и таймаутов) побочный эффект от N > 0 идентичных запросов является таким же, как и от одного запроса.


    Методы GET, HEAD, PUT и DELETE имеют это свойство.

    8.2. Опции

    Метод OPTIONS представляет собой запрос информации о коммуникационных опциях, доступных в цепочке запрос/отклик, идентифицированной Request-URI. Этот метод позволяет клиенту определить опции и/или требования, связанные с ресурсами, или возможности сервера, не прибегая к операциям по извлечению и пересылке каких-либо файлов.

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

    Если Request-URI тождественен символу звездочка ("*"), то запрос OPTIONS будет относиться ко всему серверу. Отклик 200 должен включать в себя любые поля заголовка, которые указывают на опционные характеристики используемого сервера (например, Public), включая любые расширения неопределенные в данной спецификации, в дополнение к любым общим используемым полям заголовка. Как описано в разделе 4.1.2, запрос "OPTIONS *" может быть реализован через прокси путем спецификации сервера места назначения в Request-URI без указания прохода. Если Request-URI не равен звездочке, запрос OPTIONS относится только к опциям, которые доступны при обмене с данным ресурсом. Отклик 200 должен включать любые поля заголовка, которые указывают опционные характеристики используемого сервера и применимы к данному ресурсу (напр., Allow), включая любые расширения, не описанные в данной спецификации. Если запрос OPTIONS проходит через прокси, то он должен редактировать отклик и удалять те опции, которые не доступны для реализации через данный прокси-сервер.

    8.3 Метод GET

    Метод GET предполагает извлечение любой информации (в форме объекта), заданной Request-URI. Если Request-URI относится к процессу, генерирующему данные, то в результате в виде объекта будут присланы эти данные, а не исходный текст самого процесса, если только этот текст не является результатом самого процесса.



    Семантика метода меняется на "условный GET", если сообщение-запрос включает в себя поля заголовка If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match или If-Range. Метод условного GET запрашивает, пересылку объекта только при выполнении требований, описанных в соответствующих полях заголовка. Метод условного GET имеет целью уменьшить ненужное использование сети путем разрешения актуализации кэшированых объектов без посылки множественных запросов или пересылки данных, которые уже имеются у клиента. Семантика метода GET меняется на "частичный GET", если сообщение запроса включает в себя поле заголовка Range. Запросы частичного GET, которые предназначены для пересылки лишь части объекта, описаны в разделе 13.36. Метод частичного GET ориентирован на уменьшение ненужного сетевого обмена, допуская пересылку лишь части объекта, которая нужна клиенту, и не пересылая уже имеющихся частей.

    Отклик на запрос GET буферизуется, тогда и только тогда, когда это согласуется с требованиями буферизации, рассмотренными в разделе 12.

    8.4. Метод HEAD

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

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

    8.5. Метод POST

    Метод POST используется при заявке серверу принять вложенный в запрос объект в качестве нового вторичного ресурса, идентифицированного Request-URI в Request-Line.


    POST создан для обеспечения однородной схемы реализации следующих функций:

  • Аннотация существующего ресурса;


  • Помещение сообщения на электронную доску объявлений, в группу новостей, почтовый список или какую-то другую группу статей;


  • Выдача блока данных, такого как при передаче формы процессу ее обработки;


  • Расширение базы данных с помощью операции добавления (append).


  • Реальная операция, выполняемая методом POST, определяется сервером и обычно зависит от Request-URI. Присланный объект является вторичным по отношению к URI в том же смысле, в каком файл является вторичным по отношению к каталогу, в котором он находится, а статья новостей - вторичной по отношению к группе новостей, куда она помещена, или запись – по отношению к базе данных.

    Операция, выполняемая методом POST, может не иметь последствий для ресурса, который может быть идентифицирован URI. В этом случае приемлемым откликом является 200 (OK) или 204 (No Content – никакого содержимого), в зависимости от того, включает ли в себя отклик объект, описывающий ресурс.

    Если ресурс был создан на исходном сервере, отклик должен быть равен 201 (Created - создан) и содержать объект, который описывает статус запроса и относится к новому ресурсу и заголовку Location (см. раздел 13.30).

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

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

    8.6. Метод PUT

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


    Если новый ресурс создан, исходный сервер должен информировать об этом агента пользователя, послав код отклик 200 (OK) или 204 (No Content – никакого содержимого) и тем самым, объявляя об успешно выполненном запросе. Если ресурс не может быть создан или модифицирован с помощью Request-URI, должен быть послан соответствующий код отклика, который отражает характер проблемы. Получатель объекта не должен игнорировать любой заголовок Content-* (например, Content-Range), который он не понял или не использовал, а должен в таком случае вернуть код отклика 501 (Not Implemented – не использовано).

    Если запрос проходит через кэш и Request-URI идентифицирует один или более кэшированных объектов, эти объекты должны рассматриваться как устаревшие. Отклики этого метода не должны кэшироваться.

    Фундаментальное отличие между запросами POST и PUT отражается в различных значениях Request-URI. URI в запросе POST идентифицирует ресурс, который будет работать со вложенным объектом. Этот ресурс может быть процессом приемки данных, шлюзом к другому протоколу или отдельным объектом, который воспринимает аннотации. Напротив, URI в запросах PUT идентифицируют объекты, заключенные в запросе, – агент пользователя знает, какой URI применить и сервер не должен пытаться посылать запрос другому ресурсу. Если сервер хочет, чтобы запрос был направлен другому URI, он должен послать отклик 301 (Moved Permanently). Агент пользователя может принять свое собственное решение относительно того, следует ли переадресовывать запрос.

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



    8.7. Метод DELETE

    Метод DELETE требует, чтобы исходный сервер уничтожил ресурс, идентифицируемый Request-URI. Этот метод на исходном сервере может быть отвергнут вмешательством человека (или каким-то иным путем). Клиент не может гарантировать, что операция была выполнена, даже если возвращенный статусный код указывает, что операция завершилась успешно. Однако, сервер не должен сообщать об успехе, если за время отклика он не намерен стереть ресурс или переместить его в недоступное место.

    Сообщение об успехе должно иметь код 200 (OK), если отклик включает объект, описывающий статус; 202 (Accepted - принято), если операция еще не произведена или 204 (No Content – Никакого содержимого), если отклик OK, но объекта в нем нет.

    Если запрос проходит через кэш, а Request-URI идентифицирует один или более кэшированных объектов, эти объекты следует считать устаревшими (stale). Отклики на этот метод не кэшируемы.

    8.8. Метод TRACE

    Метод TRACE используется для того, чтобы запустить удаленный цикл сообщения-запроса на прикладном уровне. Конечный получатель запроса должен отослать полученное сообщение назад клиенту в виде тела объекта (код = 200 (OK)). Конечным получателем является либо исходный сервер, либо первый прокси или шлюз для получения значения Max-Forwards (0) в запросе (см. раздел 13.31). Запрос TRACE не должен включать в себя объект.

    TRACE позволяет клиенту видеть, что получено на другом конце цепи запроса и использовать эти данные для тестирования или диагностики. Значение поля заголовка Via (раздел 13.44) представляет особый интерес, так как оно позволяет отследить всю цепочку запроса. Использование поля заголовка Max-Forwards позволяет клиенту ограничить длину цепи запроса, которая полезна для тестирования цепи прокси, переадресующих сообщения по замкнутому кругу.

    В случае успеха отклик должен содержать все сообщение-запрос с Content-Type = "message/http". Отклики этого метода не должны кэшироваться.

    4.5.6.1.9. Определения статусных кодов

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



    9.1. Информационный 1xx

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

    9.1.1. 100 Continue (продолжение)

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

    9.1.2. 101 Switching Protocols (Переключающие протоколы)

    Сервер оповещает клиента о том, что он понял и принял к исполнению запрос. С помощью поля заголовка сообщения Upgrade (раздел 13.41) клиент уведомляется об изменении прикладного протокола для данного соединения. Сервер переходит на протокол, определенный в поле заголовка отклика Upgrade, немедленно после получения пустой строки, завершающей отклик 101.

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

    9.2. Successful 2xx (Успешная доставка)

    Этот класс статусного кода индицирует, что запрос клиента благополучно получен, понят и принят к исполнению.

    9.2.1. 200 OK

    Запрос успешно исполнен. Информация, возвращаемая вместе с откликом, зависит от метода, использованного запросом, например:

    GET - в качестве отклика посылается объект, соответствующий запрошенному ресурсу;

    HEAD – в качестве отклика посылаются поля заголовка объекта (без какого-либо тела), соответствующего запрошенному ресурсу;



    POST - объект, описывающий или содержащий результат операции;

    TRACE – объект, содержащий сообщение-запроса, в виде, полученном оконечным сервером.

    9.2.2. 201 Created (Создано)

    Запрос исполнен и в результате создан новый ресурс. Вновь созданный ресурс может быть доступен через URI, присланный в объекте отклика, со значащей частью URL ресурса в поле заголовка Location. Исходный сервер должен создать ресурс до отправки статусного кода 201. Если операция не может быть выполнена немедленно, сервер вместо этого должен откликнуться статусным кодом 202 (Accepted).

    9.2.3. 202 Accepted (Принято)

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

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

    9.2.4. 203 Non-Authoritative Information (Не надежная информация)

    Присылаемая в ответ метаинформация в заголовке объекта не идентифицируется, как полученная от исходного сервера, ее следует скорее считать косвенной, полученной опосредовано. Например, включение местной аннотационной информации о ресурсе может иметь последствия для мета информации, известной исходному серверу. Использование данного кода отклика не является обязательным и целесообразно лишь в случае, когда отклик мог бы быть равен 200 (OK).

    9.2.5. 204 No Content (Никакого содержимого)

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


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

    Отклик 204 не должен включать тела сообщения и всегда завершается пустой строкой после полей заголовка.

    9.2.6. 205 Reset Content (Сброс содержимого)

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

    9.2.7. 206 Partial Content (Частичное содержимое)

    Сервер исполнил частично запрос GET для заданного ресурса. Запрос должен включать поле заголовка Range (раздел 13.36), указывающее на желательный интервал (range). Отклик должен включать поле заголовка Content-Range (раздел 13.17), указывающее диапазон данных, включенных в отклик, или множественные байтные интервалы (multipart/byteranges) Content-Type, включающие поля Content-Range для каждой из частей. Если множественные байтные интервалы не используются, поле заголовка Content-Length в отклике должно соответствовать действительному числу октетов в теле сообщения. Кэш, который не поддерживает заголовки Range и Content-Range, не должен кэшировать отклики 206 (Partial).

    9.3. Redirection 3xx (Переадресация)

    Этот класс статусных кодов указывает, что для выполнения запроса, нужны дальнейшие действия агента пользователя. Необходимые действия могут быть выполнены агентом пользователя без взаимодействия с пользователем, тогда и только тогда, когда используемый метод соответствует GET или HEAD. Агент пользователя не должен автоматически переадресовывать запрос более чем 5 раз, так как такая переадресация обычно свидетельствует о зацикливании запроса.

    9.3.1. 300 Multiple Choices (Множественный выбор)

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


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

    Если это только не был запрос HEAD, отклик должен включать объект, содержащий список характеристик ресурсов и их адресов, из которых пользователь или агент пользователя может выбрать наиболее подходящий. Формат объекта специфицируется типом среды, заданным полем заголовка Content-Type. В зависимости от формата и возможностей агента пользователя, выбор наиболее подходящего варианта может быть выполнен автоматически. Однако, эта спецификация не определяет какого-либо стандарта для такого автоматического выбора.

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

    9.3.2. 301 Moved Permanently (Постоянно перемещен)

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

    Если новый URI является адресом (location), его URL должен быть задан в поле Location отклика. Если метод запроса не HEAD, объект отклика должен содержать короткое гипертекстное замечание с гиперсвязью, указывающей на новый URI.

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



    Замечание: При автоматической переадресации запроса POST, получив статусный код 301, некоторые существующие агенты пользователя HTTP/1.0 ошибочно меняют его на запрос GET.

    9.3.3. 302 Moved Temporarily (Временно перемещен)

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

    Если новый URI является адресом (location), его URL должен задаваться полем Location отклика. Если запрошенный метод не HEAD, объект отклика должен содержать короткое гипертекстное замечание с гиперсвязью, указывающей на новый URI.

    Если в ответ на запрос, отличный от GET или HEAD, получен статусный код 302, агент пользователя не должен автоматически переадресовывать запрос, если это не может быть подтверждено пользователем, так как это может изменить условия, при которых был выдан запрос.

    Замечание: Когда после получения статусного кода 302 автоматически переадресуется запрос POST, некоторые существующие агенты пользователя HTTP/1.0 ошибочно меняют его на запрос GET.

    9.3.4. 303 See Other (смотри другие)

    Отклик на запрос может быть найден под разными URI. Его следует извлекать с помощью метода GET. Этот метод первоначально создан для того, чтобы позволить переадресацию агента пользователя на выбранный ресурс при запуске скрипта с помощью POST. Новый URI не является заменой ссылки для первоначально запрошенного ресурса. Отклик 303 не кэшируется, но отклик на второй (переадресованный) запрос может кэшироваться.

    Если новый URI является адресом (location), его URL должно быть задано в поле Location отклика. Если метод запроса не HEAD, объект отклика должен содержать гипертекстовую ссылку на новый URI.

    9.3.5. 304 Not Modified (Не модифицировано)

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


    Отклик не должен содержать тела сообщения.

    Отклик должен включать поля заголовка:

  • Дата


  • ETag и/или Content-Location, если заголовок был послан в рамках отклика 200 на тот же самый запрос


  • Expires, Cache-Control и/или Vary, если значение поля может отличаться от посланного в каком-либо предыдущем отклике того же типа


  • Если условный GET использовал строгий валидатор кэша (см. раздел 12.8.3), отклик не должен содержать других заголовков объекта. В противном случае (напр., условный GET использовал слабый валидатор), отклик не должен включать в себя другие заголовки. Это предотвращает несогласованности между кэшированными телами объектов и актуализованными заголовками (updated headers).

    Если отклик 304 указывает на то, что объект не кэширован, тогда кэш должен

    игнорировать отклик и повторить запрос уже в безусловном режиме.

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

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

    9.3.6. 305 Use Proxy (Используйте прокси)

    Запрошенный ресурс должен иметь доступ через прокси-сервер, указанный в поле Location. Поле Location задает URL прокси-сервера. Предполагается, что получатель повторит запрос через прокси.

    9.4. Client Error 4xx (Ошибка клиента)

    Класс статус кодов 4xx предназначен для случаев, когда клиент допустил ошибку. За исключением случая отклика на запрос HEAD, серверу следует включить объект, содержащий объяснение ошибочной ситуации, а также указать, является ли ситуация временной или постоянной. Эти статусные коды применимы к любому методу запросов. Агенту пользователя следует отобразить все объекты.

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



    9.4.1. 400 Bad Request (Плохой запрос)

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

    9.4.2. 401 Unauthorized (Не авторизован)

    Запрос требует авторизации пользователя. Отклик должен включать в себя поле заголовка WWW-Authenticate (раздел 13.46), содержащее требование (challenge), применимое к запрошенному ресурсу. Клиент может повторить запрос с соответствующим содержимым поля заголовка Authorization (раздел 13.8). Если запрос уже включал допуск в поле Authorization, тогда отклик 401 указывает на то, что данный допуск не работает. Если отклик 401 содержит то же требование, что и предшествующий отклик, а агент пользователя уже пробовал пройти идентификацию по крайней мере хотя бы раз, тогда пользователю следует предоставить объект, содержащийся в отклике, так как он может содержать полезную диагностическую информацию. Идентификация доступа HTTP описана в разделе 10.

    9.4.3. 402 Необходима оплата

    Этот код зарезервирован для использования в будущем.

    9.4.4. 403 Forbidden (Запрещено)

    Сервер понял запрос, но отказался его исполнить. Авторизация не поможет и повторять запрос не следует. Если метод запроса не HEAD, а сервер желает открыто объявить причину неисполнения запроса, то ему следует описать соображения, по которым запрос отклонен Этот статусный код обычно используется, когда сервер не хочет показывать, почему запрос отклонен, или когда другой отклик не подходит.

    9.4.5. 404 Not Found (Не найдено)

    Сервер не нашел ничего, отвечающего Request-URI. Не приводится никаких данных о том, являются ли эта ситуация временной или постоянной.

    Если сервер не хочет сделать эту информацию открытой для клиента, вместо этого может использоваться статусный код 403. Статусный код 410 (Gone - Утрачен) следует использовать, если сервер знает за счет некоторого внутреннего механизма конфигурации, что старый ресурс постоянно недоступен и не имеет нового адреса его размещения.

    9.4.6. 405 Method Not Allowed (Метод не разрешен)



    Метод, специфицированный в Request-Line, не разрешен для ресурса, указанного Request-URI. Отклик должен включать заголовок Allow, содержащий список разрешенных методов для запрошенного ресурса.

    9.4.7. 406 Not Acceptable (Не приемлемо)

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

    Если это не запрос HEAD, отклик должен включать объект, содержащий список доступных характеристик объекта и адреса, где пользователь или агент пользователя может выбрать нечто наиболее подходящее. Формат объекта специфицируется типом среды, приведенным в поле заголовка Content-Type. В зависимости от формата и возможностей агента пользователя, оптимальный выбор может быть сделан автоматически. Однако данная спецификация не определяет какого-либо стандарта для такого автоматического выбора.

    Замечание. HTTP/1.1 серверам разрешено присылать отклики, которые неприемлемы согласно заголовкам accept, присланным в запросе. В некоторых случаях, может оказаться предпочтительнее послать отклик 406. Агенты пользователя могут просматривать заголовки приходящих откликов с тем, чтобы определить, являются ли они приемлемыми. Если отклик не может быть воспринят, агенту пользователя следует временно прервать прием данных и запросить пользователя принять решение о дальнейших действиях.

    9.4.8. 407 Proxy Authentication Required (Необходима идентификация прокси)

    Этот статусный код подобен 401 (Unauthorized), но указывает, что клиент должен сначала авторизоваться на прокси-сервере. Прокси должен прислать в ответ поле заголовка Proxy-Authenticate (раздел 13.33), содержащего требования, реализуемые на прокси для запрошенного ресурса. Клиент может повторить запрос с подходящим полем заголовка Proxy-Authorization (раздел 13.34). Авторизация доступа HTTP описана в разделе 10.

    9.4.9. 408 Request Timeout (Таймаут запроса)

    Клиент не выдал запрос в пределах временного интервала, в течение которого сервер его ожидал.


    Клиент может повторить запрос без модификаций в любое время.

    9.4.10. 409 Conflict (Конфликт)

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

    Конфликты наиболее вероятно происходят в результате запроса PUT. Если задействована версия и объект операции PUT вызывает изменение ресурса, которые конфликтуют с изменениями внесенными запросом, выполненным ранее, сервер может использовать отклик 409 для того, чтобы указать на невозможность завершить выполнение запроса. В этом случае объект отклика должен содержать список отличий между двумя версиями формата, определенном откликом Content-Type.

    9.4.11. 410 Gone (Исчез)

    Запрошенный ресурс не является более доступным на сервере и не известен указатель переадресации. Это условие следует считать постоянным. Клиенты с возможностями редактирования связей должны ликвидировать ссылки на Request-URI после подтверждения пользователем. Если сервер не знает или не имеет возможности определить, является ли данное условие постоянным или временным, следует использовать отклик со статусным кодом 404 (Not Found). Этот отклик можно кэшировать, если не указано обратного.

    Отклик 410 первоначально предназначался для того, чтобы помочь работе задач в WWW-среде путем сообщения получателю о том, что ресурс заведомо недостижим и владелец сервера хотел бы, чтобы связи с этим ресурсом были удалены. Такое событие является типичным для ограниченного периода времени и для ресурсов, принадлежащих частным лицам, которые не работают более с данным сервером. Не обязательно отмечать все постоянно недоступные ресурсы, как исчезнувшие (Gone) или сохранять такую пометку произвольное время – это оставлено на усмотрение собственника сервера.



    9.4.12. 411 Length Required (Необходима длина)

    Сервер отказывается принять запрос без определенного значения Content-Length. Клиент может повторить запрос, если он добавит корректное значение поля заголовка Content-Length, содержащего длину тела сообщения.

    9.4.13. 412 Precondition Failed (Предварительные условия не выполнены)

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

    9.4.14. 413 Request Entity Too Large (Объект запроса слишком велик)

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

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

    9.4.15. 414 Request-URI Too Long (URI запроса слишком велик)

    Сервер отказывается обслужить запрос, потому что Request-URI длиннее, чем сервер способен интерпретировать. Это редкое обстоятельство может возникнуть только, когда клиент не корректно преобразует запрос POST в GET с длинной информацией запроса. При этом клиент ныряет в "черную дыру" переадресаций. Примером может служить преадресованный URL префикс, который указывает на свой суффикс, или случай атаки сервера клиентом, который пытается использовать дыры в системе безопасности, имеющиеся у клиентов с фиксированной емкостью буферов для работы с Request-URI.

    9.4.16. 415 Unsupported Media Type (Неподдерживаемый тип среды)

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



    9.5. Сервер ошибок 5xx

    Статусный код отклика, начинающийся с цифры "5", указывает на случаи, когда сервер опасается, что он ошибся или не может реализовать запрос. За исключением случаев, когда обрабатывается запрос HEAD, серверу следует включить объект, содержащий объяснение создавшейся ошибочной ситуации и указывающей на то, является ли ситуация временной или постоянной. Агенту пользователя следует отобразить пользователю любой объект, включенный в отклик. Эти коды откликов применимы для любых методов запроса.

    9.5.1. 500 Internal Server Error (Внутренняя ошибка сервера)

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

    9.5.2. 501 Not Implemented (Не применимо)

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

    9.5.3. 502 Bad Gateway (Плохой шлюз)

    Сервер при работе в качестве шлюза или прокси получил неверный отклик от вышестоящего сервера, к которому он обратился, выполняя запрос.

    9.5.4. 503 Service Unavailable (Услуга не доступна)

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

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

    9.5.5. 504 Gateway Timeout (Таймаут шлюза)

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

    9.5.6. 505 HTTP Version Not Supported (Версия не поддерживается)

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


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

    4.5.6.1.10. Идентификация доступа

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

    Auth-scheme = token
    auth-param = token "=" quoted-string
    Сообщение-отклик 401 (Unauthorized) используется исходным сервером для посылки требования авторизации агенту пользователя. Этот отклик должен включать в себя поле заголовка WWW-Authenticate, содержащее, по крайней мере, одно требование доступа к запрашиваемому ресурсу.

    Challenge = auth-scheme 1*SP realm *( "," auth-param )
    Realm = "realm" "=" realm-value
    realm-value = quoted-string
    Атрибут области realm (не зависит от применения строчных или прописных букв) необходим для всех схем идентификации (authentication), которые посылают требования. Значение атрибута realm (чувствительно к применению строчных и прописных букв), в комбинации с каноническим корневым URL (см. раздел 4.1.2) сервера доступа, определяет пространство защиты. Эти области позволяют разделить защищенные ресурсы на сервере на ряд защищенных зон, каждая со своей собственной схемой идентификации и/или идентификационной базой данных. Значением атрибута области является строка, обычно присваиваемая исходным сервером, которая может иметь специфическую емантику для каждой схемы идентификации.

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


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

    credentials = basic-credentials
    | auth-scheme #auth-param

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

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

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

    Прокси-серверы должны быть полностью прозрачны по отношению авторизации агентов пользователя. То есть, они должны переадресовывать в неприкосновенном виде заголовки WWW-Authenticate и Authorization, согласно правилам описанным в разделе 13.8.

    HTTP/1.1 позволяет клиенту передать идентификационную информацию в прокси и обратно с использованием заголовков Proxy-Authenticate и Proxy-Authorization.

    10.1 Базовая схема идентификации (Authentication)

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



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

    При получении неавторизованного запроса для URI в пределах зоны защиты (protection space), сервер может реагировать посылкой требования в виде:

    WWW-Authenticate: Basic realm="WallyWorld"

    где "WallyWorld" – строка присвоенная сервером для идентификации зоны защиты Request-URI.

    Чтобы получить авторизацию клиент посылает свое имя и пароль, разделенные символом двоеточие (":"), и закодированные согласно base64.

    basic-credentials = "Basic" SP basic-cookie

    basic-cookie =

    user-pass = userid ":" password

    userid = *

    password = *TEXT

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

    Если агент пользователя хочет послать имя пользователя "Aladdin" и пароль "Сезам открой", он использует следующее поле заголовка:

    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

    Смотри раздел 14 по поводу соображений безопасности, связанных с базовой авторизацией.

    10.2 Краткое изложение схемы авторизации

    Краткое изложение идей авторизации для HTTP представлено в документе RFC-2069 [32].

    4.5.6.1.11. Согласование содержимого

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

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



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

    11.1 Согласование, управляемое сервером

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

    Согласование, управляемое сервером предпочтительнее, когда алгоритм выбора из числа доступных представлений трудно описать агенту пользователя. Согласование под управлением сервера привлекательно тогда, когда сервер хочет послать свои “наилучшие предложения” клиенту вместе с первым откликом (надеясь избежать задержек RTT последующих запросов, если предложение удовлетворит пользователя). Для того чтобы улучшить предложения сервера, агент пользователя может включить в запрос поля заголовка (Accept, Accept-Language, Accept-Encoding, и т.д.), которые описывают его предпочтения для данного запроса. Согласование под управлением сервера имеет следующие недостатки:

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




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


    3. Это усложняет реализацию исходного сервера и алгоритм генерации откликов на запросы.


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


    HTTP/1.1 включает в себя следующие поля заголовка запроса для активации согласования, управляемого сервером, через описание возможностей агента пользователя и предпочтений самого пользователя: Accept (раздел 13.1), Accept- Charset (раздел 13.2), Accept-Encoding (раздел 13.3), Accept-Language (раздел 13.4) и User-Agent (раздел 13.42). Однако, исходный сервер не ограничен этими рамками и может варьировать отклик, основываясь на свойствах запроса, включая информацию помимо полей заголовка запроса или используя расширения полей заголовка нерассмотренные в данной спецификации.

    Исходные серверы HTTP/1.1 должны включать соответствующие, управляемом сервером. Поле Vary описывает пределы, в которых может варьироваться отклик (то есть, пределы, в которых исходный сервер выбирает свои “наилучшие предложения” отклика из многообразия редставлений).

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

    11.2. Согласование, управляемое агентом (Agent-driven Negotiation)

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


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

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

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

    HTTP/1.1 определяет статусные коды 300 (Multiple Choices – множественный выбор) и 406 (Not Acceptable – Не приемлем) для активации согласования под управлением агента, когда сервер не хочет или не может обеспечить свой механизм согласования.

    11.3 Прозрачное согласование (Transparent Negotiation)

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

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

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


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

    4.5.6.1.12 Кэширование в HTTP

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

    Кэширование представляется бесполезным, если оно значительно не улучшит работу. Целью кэширования в HTTP/1.1 является исключение во многих случаях необходимости посылать запросы, а в некоторых других случаях - полные отклики. При этом уменьшается число необходимых RTT для многих операций. Для этих целей используется механизм “истечения срока” (expiration) (см. раздел 12.2). Одновременно снижаются требования к полосе пропускания сети, для чего применяется механизм проверки пригодности (см. раздел 12.3).

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

    Следовательно, протокол HTTP/1.1 обеспечивает следующие важные моменты:

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




  • Базовым принципом является возможность для клиентов детектировать любое ослабление семантической прозрачности.

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

    12.1 Корректность кэша

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

    1. Он был проверен на эквивалентность с тем, который бы прислал исходный сервер при соответствующем запросе (раздел 12.3);
    2. Он достаточно нов (см. раздел 12.2). В варианте по умолчанию это означает, что он отвечает минимальным требованиям клиента, сервера и кэша по новизне (см. раздел 13.9). Если исходный сервер задает такие требования, то это только его требования на новизну.


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


    4. Это сообщение-отклик 304 (Not Modified), 305 (Proxy Redirect), или ошибка (4xx или 5xx).


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

    Если кэш получает отклик (полный отклик или код 304 (Not Modified)), который уже не является свежим, кэш должен переадресовать его запросившему клиенту без добавления нового предупреждения, и не удаляя существующего заголовка Warning. Кэшу не следует пытаться перепроверить отклик, так как это может привести к бесконечному зацикливанию. Агент пользователя, который получает устаревший отклик без Warning, может отобразить предупреждение для пользователя.



    12.2 Предупреждения

    Когда кэш присылает опосредованный отклик, который “недостаточно свеж” (с точки зрения условия 2 раздела 12.1), к нему должно быть присоединено предупреждение об этом с использованием заголовка Warning. Это предупреждение позволяет клиентам предпринять соответствующие действия.

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

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

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

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

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

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

    Заголовок Warning и определенные в настоящий момент предупреждения описаны в разделе 13.45.

    12.3 Механизмы управления кэшем

    Базовым механизмом кэша в HTTP/1.1 (времена таймаутов и валидаторы) являются неявные директивы кэша.


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

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

    Однако в некоторых случаях директивы Cache-Control сформулированы так, что явно ослабляют семантическую прозрачность (например, "max-stale" или "public"). Директивы Cache-Control подробно описаны в разделе 13.9.

    12.4 Прямые предупреждения агента пользователя

    Многие агенты пользователя позволяют переписывать базовый механизм кэширования. Например, агент пользователя может специфицировать то, какие кэшированные объекты (даже явно старые) не проверять на новизну. Или агент пользователя может всегда добавлять "Cache-Control: max-stale=3600" к каждому запросу.

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

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



    12.5 Исключения для правил и предупреждений

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

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

    12.6 Работа под управлением клиента

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

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

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

    12.7. Модель истечения срока годности

    12.7.1 Определение срока годности под управлением сервера



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

    Предполагается, что серверы припишут в явном виде значения времени пригодности (expiration time) откликам в предположении, что объекты вряд ли изменятся семантически значимым образом до истечения этого времени. Это сохраняет семантическую прозрачность при условии, что время жизни выбрано корректно.

    Механизм времени пригодности (expiration) применим только к откликам, взятым из кэша, а не к откликам, полученным из первых рук и переадресованных запрашивающему клиенту.

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

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

    Серверы определяют реальные времена сроков пригодности, используя заголовок Expires, или директиву максимального возраста заголовка Cache-Control.

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

    12.7.2 Эвристический контроль пригодности

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


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

    12.7.3. Вычисление возраста

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

    В этом обсуждении используется термин “сейчас” для обозначения “текущего показания часов на ЭВМ, выполняющей вычисление". ЭВМ, которая использует HTTP, и в особенности ЭВМ, работающие в качестве исходных серверов и кэшей, должны использовать NTP [28] или некоторый схожий протокол для синхронизации их часов с использованием общего точного временного стандарта.

    Следует обратить внимание на то, что HTTP/1.1 требует от исходного сервера посылки в каждом отклике заголовка Date, сообщая время, когда был сгенерирован отклик. Мы используем термин "date_value" для обозначения значения заголовка Date, в форме, приемлемой для арифметических операций.

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

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

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


    Возраст отклика может быть вычислен двумя совершенно независимыми способами.

    1. Текущее время минус date_value, если местные часы синхронизованы с часами исходного сервера. Если результат отрицателен, он заменяется на нуль.


    2. age_value, если все кэши вдоль пути отклика поддерживают HTTP/1.1.


    Таким образом, мы имеем два независимых способа вычисления возраста отклика при его получении, допускается их комбинирование, например:

    corrected_received_age = max(now - date_value, age_value)

    и, поскольку мы имеем синхронизованные часы, или все узлы вдоль пути поддерживают HTTP/1.1, получается надежный (консервативный) результат.

    Заметьте, что поправка применяется в каждом кэше HTTP/1.1 вдоль пути так, что, если встретится на пути кэш HTTP/1.0, правильное значение возраста будет получено потому, что его часы почти синхронизованы. Нам не нужна сквозная синхронизация (хотя ее не плохо бы иметь).

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

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

    corrected_initial_age = corrected_received_age + (now - request_time)

    где "request_time" равно времени (согласно местным часам), когда был послан запрос, вызвавший данный отклик.

    Резюме алгоритма вычисления возраста при получении отклика кэшем:

    /*

    * age_value

    * равно значению Age: заголовок, полученный кэшем с этим откликом.
    * date_value

    * равно значению Date исходного сервера: заголовок
    <


    /p> * request_time

    * равно местному времени, когда кэш сделал запрос, который явился причиной этого кэшированного отклика
    * response_time

    * равно местному времени, когда кэш получил отклик
    * now

    * равно текущему (местному) времени
    */

    apparent_age = max(0, response_time - date_value);

    corrected_received_age = max(apparent_age, age_value);

    response_delay = response_time - request_time;

    corrected_initial_age = corrected_received_age + response_delay;

    resident_time = now - response_time;

    current_age = corrected_initial_age + resident_time;

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

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

    12.4 Вычисление времени жизни (Expiration)

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

    Мы используем термин "expires_value" для обозначения содержимого заголовка Expires. Для обозначения числа секунд, определенного директивой максимального возраста заголовка Cache-Control отклика (см. раздел 13.9), используется термин "max_age_value".

    Директива максимального возраста имеет приоритет перед Expires, так если max-age присутствует в отклике, вычисление производится просто:



    freshness_lifetime = max_age_value

    В противном случае, если в отклике присутствует Expires, то вычисления осуществляются следующим образом:

    freshness_lifetime = expires_value - date_value

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

    Если ни Expires, ни Cache-Control: max-age не определяют максимальный возраст отклика, а отклик не содержит других ограничений на кэширование, кэш может вычислить время жизни, используя эвристику. Если эта величина больше 24 часов, кэш должен присоединить к отклику Warning 13, если такое предупреждение еще не добавлено.

    Кроме того, если отклик имеет время Last-Modified, эвристическое значение времени жизни должно быть не больше некоторой доли времени, прошедшего со времени модификации. Типичное значение этой доли может составлять 10%.

    Расчет того, истекло ли время жизни отклика, достаточно прост:

    response_is_fresh = (freshness_lifetime > current_age)

    12.5 Устранение неопределенности значений времени жизни

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

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

    повторить запрос с директивой "Cache-Control: max-age=0" (см. раздел 13.9), чтобы усилить контроль со стороны исходного сервера.

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



    12.6 Неопределенность из-за множественных откликов

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

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

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

    Cache-Control: max-age=0

    Чтобы заставить некоторые промежуточные кэши сверить свои копии непосредственно с исходным сервером, или

    Cache-Control: no-cache

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

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

    12.8 Модель проверки пригодности

    Когда кэш имеет устаревшую запись, которую бы он хотел использовать в качестве отклика на запрос клиента, он сначала должен произвести сверку с базовым сервером (или возможно промежуточным кэшем, содержащим свежий отклик), чтобы убедиться, что кэшированная запись все еще применима. Мы это называем проверкой пригодности записи кэша ("validating"). Так как мы не хотим пересылки всей записи, если с ней все в порядке, и мы не хотим тратить лишнее время из-за RTT в случае, если запись более не пригодна, протокол HTTP/1.1 поддерживает использование условных методов.



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

    Сервер сверяет полученный валидатор с текущим валидатором объекта и, если они совпадают, посылается отклик с соответствующим статусным кодом (обычно, 304 (Not Modified)) и без тела объекта. В противном случае он возвращает полный отклик (включая тело объекта). Таким образом, мы избегаем передачи полного отклика, если валидаторы взаимно согласованы.

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

    В HTTP/1.1 условный запрос выглядит точно также как и обычный запрос того же самого ресурса, за исключением того, что он несет в себе специальный заголовок (который содержит валидатор), и неявно меняет метод (обычный GET) на условный.

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

    Замечание. Отклик, который не имеет валидатора, может кэшироваться и использоваться до истечения его срока годности, если только это явно не запрещено директивой Cache-Control. Однако, кэш не может выполнить условную доставку ресурса, если он не имеет валидатора для запрашиваемого объекта, что означает отсутствие возможности его актуализации после истечения срока годности.

    12.8.1 Даты последней модификации

    Значение поля заголовка объекта Last-Modified часто используется кэшем в качестве валидатора. Иными словами, запись в кэше рассматривается как пригодная, если объект не был модифицирован с момента, указанного в Last-Modified.



    12.8. 2 Валидаторы кэша для меток объектов (Entity Tag Cache Validators)

    Значение поля заголовка объекта ETag (Entity Tag - метка объекта), представляет собой “непрозрачный” валидатор кэша. Это может гарантировать большую надежность при контроле пригодности в ситуациях, когда неудобно запоминать модификации дат, где недостаточно односекундного разрешения для значения даты HTTP или где исходный сервер хочет избежать определенных парадоксов, которые могут возникнуть от использования дат модификации.

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

    12.8.3 Слабые и сильные валидаторы

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

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

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

    Замечание. Примером сильного валидатора является целое число, которое увеличивается на единицу всякий раз, когда в объект вносится какое-либо изменение.

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



    Поддержка слабых валидаторов является опционной. Однако слабый валидатор позволяет более эффективно кэшировать эквивалентные объекты.

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

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

    Единственной функцией протокола HTTP/1.1, определенной для валидаторов, является сравнение. Существует две функции сравнения валидаторов, в зависимости от того, допускает ли контекст использование слабых валидаторов или нет:

  • Функция сильного сравнения. Для того, чтобы считаться равными оба валидатора должны быть идентичными, и не один из них не должен быть слабым.


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


  • Функция слабого сравнения может быть использована для простых (non-subrange – не фрагментных) GET-запросов. Функция сильного сравнения должна быть использована во всех прочих случаях.

    Метка объекта является сильной, если она не помечена явно как слабая. В разделе 2.11 рассматривается синтаксис меток объектов.

    Параметр Last-Modified time, при использовании в качестве валидатора запроса, является неявно (подразумевается) слабым, если не возможно установить, что он сильный, используя следующие правила:

  • Валидатор сравнивается исходным сервером с текущим рабочим валидатором для данного объекта и,


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


    Или


  • Валидатор предполагается использовать клиентом в заголовке If-Modified-Since или If-Unmodified-Since, так как клиент имеет запись в кэше для соответствующего объекта, и


  • Эта запись в кэш включает в себя значение Date, которое определяет время, когда исходный сервер послал оригинал запроса, и


  • Предлагаемый параметр Last-Modified time соответствует моменту времени, по крайней мере, на 60 секунд раньше значения Date.


  • или

  • Валидатор сравнивается промежуточным кэшем с валидатором, запомненным в записи для данного объекта, и


  • Эта запись в кэше включает в себя значение Date, которое определяет время, когда исходный сервер послал оригинал запроса, и


  • Предлагаемый параметр Last-Modified time соответствует моменту времени, по крайней мере, на 60 секунд раньше значения Date.


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

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

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

    12.8.4 Правила того, когда использовать метки объекта и даты последней модификации

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

    Исходный сервер HTTP/1.1:

  • Должен послать валидатор метки объекта, если только возможно его сгенерировать.




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


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


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

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

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

    Клиенты HTTP/1.1:

  • Если метка объекта была прислана исходным сервером, эта метка должна быть использована в любом условном запросе кэша (с If-Match или If-None-Match).


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


  • Если только значение Last-Modified было прислано исходным сервером HTTP/1.0, оно может использоваться в фрагментных, условных запросах кэша (с использованием If-Unmodified-Since:). Агенту пользователя следует обеспечить способ блокировки этого в случае возникновения трудностей.


  • Если и метка объекта и значение Last-Modified были присланы исходным сервером, в условных запросах кэша следует использовать оба валидатора.


    Это позволяет корректно реагировать кэшам, поддерживающим как HTTP/1.0, так и HTTP/1.1.


  • Кэш HTTP/1.1 при получении запроса должен использовать наиболее регламентирующий валидатор, когда проверяется, соответствуют ли друг другу запись в буфере клиента и собственная запись в кэше. Это единственный выход, когда запрос содержит как метку объекта, так и валидатор last-modified-date (If-Modified-Since или If-Unmodified-Since).

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

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

    12.8.5 Условия пригодности

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

    12.9. Кэшируемость отклика

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


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

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

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

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

    Отклик, полученный со статусным кодом 200, 203, 206, 300, 301 или 410, может быть запомнен кэшем и использован в ответе на последующие запросы, если директива не препятствует кэшированию. Однако, кэш, который не поддерживает заголовки Range и Content-Range не должен кэшировать отклики 206 (Partial Content).

    Отклик, полученный с любым другим статусным кодом, не должен отсылаться в ответ на последующие запросы, если только нет директив Cache-Control или других заголовков, которые напрямую разрешают это. К таким, например, относятся: заголовок Expires (раздел 13.21); "max-age", "must-revalidate", "proxy-revalidate", "public" или "private" директива Cache-Control (раздел 13.9).

    12.10 Формирование откликов кэшей

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


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

    12.10.1 Заголовки End-to-end (точка-точка) и Hop-by-hop (шаг-за-шагом)

    Для целей определения поведения кэшей и некэшурующих прокси-серверов заголовки HTTP делятся на две категории:

  • Заголовки End-to-end, которые должны быть пересланы конечному получателю запроса или отклика. Заголовки End-to-end в откликах должны запоминаться как часть объекта кэша и пересылаться в любом отклике, полученном из записи кэша.


  • Заголовки Hop-by-hop, которые имеют смысл только для одноуровневого транспортного соединения, они не запоминаются кэшем и не переадресуются прокси-серверами.


  • Следующие заголовки HTTP/1.1 относятся к категории hop-by-hop:

  • Connection


  • Keep-Alive


  • Public


  • Proxy-Authenticate


  • Transfer-Encoding


  • Upgrade


  • Все другие заголовки, определенные HTTP/1.1 относятся к категории end-to-end.

    Заголовки Hop-by-hop, вводимые в будущих версиях HTTP, должны быть перечислены в заголовке Connection, как это описано в разделе 13.10.

    12.10.2 Немодифицируемые заголовки

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

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

  • Content-Location


  • Etag


  • Expires


  • Last-Modified


  • Кэш или некэширующий прокси не должны модифицировать или добавлять следующие поля в любых запросах и в откликах, которые содержат директиву no-transform Cache-Control:

  • Content-Encoding


  • Content-Length


  • Content-Range


  • Content-Type


  • Кэш или некэширующий прокси могут модифицировать или добавлять эти поля в отклик, который не включает директиву no-transform. Если же он содержит эту директиву, следует добавить предупреждение 14 (Transformation applied), если оно еще не занесено в отклик.



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

    12.10.3 Комбинирование заголовков

    Когда кэш делает запрос серверу о пригодности ресурса и сервер выдает отклик 304 (Not Modified), кэш должен подготовить и отправить отклик, чтобы послать клиенту. Кэш использует тело объекта из записи в кэше при формировании отклика. Заголовки end-to-end записанные в кэше, используются для конструирования отклика. Исключение составляют любые end-to-end заголовки, поступившие в рамках отклика 304, они должны заместить соответствующие заголовки из записи в кэше. Если только кэш не решил удалить запись, он должен также заменить end-to-end заголовки своей записи соответствующими заголовками из полученного отклика.

    Другими словами, набор end-to-end заголовков, полученный вместе откликом переписывает все соответствующие end-to-end заголовки, из записи в кэше. Кэш может добавить к этому набору заголовки предупреждений (см. раздел 13.45).

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

    Замечание. Это правило позволяет исходному серверу использовать отклик 304 (Not Modified) для актуализации любого заголовка, связанного с предыдущим откликом для того же объекта, хотя это может не всегда иметь смысл. Это правило не позволяет исходному серверу использовать отклик 304 (not Modified) для того, чтобы полностью стереть заголовок, который был прислан предыдущим откликом.

    12.10.4 Комбинирование байтовых фрагментов

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

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



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


  • Оба валидатора кэша должны соответствовать функции сильного сравнения (см. раздел 12.8.3).


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

    12.11. Кэширование согласованных откликов

    Использование согласования содержимого под управлением сервера (раздел 11), что индицируется присутствием поля заголовка Vary в отклике, изменяет условия и процедуру, при которой кэш может использовать отклик для последующих запросов.

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

    Если представлению присвоена метка объекта, переадресуемый запрос должен быть условным и содержать метки в поле заголовка If-None-Match всех его кэшированных записей для Request-URI. Это сообщает серверу набор объектов, которые в настоящее время хранятся в кэше, так что, если любая из этих записей соответствует запрашиваемому объекту, сервер может использовать заголовок ETag в своем отклике 304 (Not Modified), чтобы сообщить кэшу, какой объект подходит. Если метка объекта нового отклика соответствует существующей записи, новый отклик должен быть использован для актуализации полей заголовка существующей записи, а результат должен быть прислан клиенту.

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


    Сервер при этом возвращает отклик 304 (Not Modified), включая метку объекта или поле Content-Location, которые указывают, какой объект должен быть использован.

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

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

    12.12. Кэши коллективного и индивидуального использования

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

    12.13. Ошибки и поведение кэша при неполном отклике

    Кэш, который получает неполный отклик (например, с меньшим числом байтов, чем специфицировано в заголовке Content-Length) может его запомнить. Однако, кэш должен воспринимать эти данные как частичный отклик. Частичные отклики могут компоноваться, как это описано в разделе 12.5.4. Результатом может быть полный или частичный отклик. Кэш не должен

    возвращать частичный отклик клиенту без явного указания на то, что он частичный, используя статусный код 206 (Partial Content). Кэш не должен возвращать частичный отклик, используя статусный код 200 (OK).

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


    В последнем случае он может вернуть отклик, полученный ранее, если только запись в кэше не содержит директиву Cache-Control "must-revalidate" (см. раздел 13.9).

    12.14. Побочные эффекты методов GET и HEAD

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

    Обратим внимание только на одно исключение из этого правила: некоторые приложения имеют традиционно используемые GET и HEAD с запросами URL (содержащими "?" в части rel_path) для выполнения операций с ощутимыми побочными эффектами. Кэши не должны

    обрабатывать отклики от таких URL, как свежие, если только сервер не присылает непосредственно значение времени жизни. Это в частности означает, что отклики от серверов HTTP/1.0 для этих URI не следует брать из кэша. Дополнительную информацию по смежным темам можно найти в разделе 8.1.1.

    12.15 Несоответствие после актуализации или стирания

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

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

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



    Некоторые методы HTTP могут сделать объект непригодным. Это либо объекты, на которые осуществляется ссылка через Request-URI, или через заголовки отклика Location или Content-Location (если они имеются). Это методы:

  • PUT


  • DELETE


  • POST


  • 12.16. Обязательная пропись (Write-Through Mandatory)

    Все методы, которые предположительно могут вызвать модификацию ресурсов исходного сервера должны быть прописаны в исходный сервер. В настоящее время сюда входят все методы кроме GET и HEAD. Кэш не должен отвечать на такой запрос от клиента, прежде чем передаст запрос встроенному (inbound) серверу, и получит соответствующего отклик от него. Это не препятствует кэшу послать отклик 100 (Continue), прежде чем встроенный сервер ответит.

    Альтернатива, известная как "write-back" или "copy-back" кэширование, в HTTP/1.1 не допускается, из-за трудности обеспечения согласованных актуализаций и проблем, связанных с отказами сервера, кэша или сети до осуществления обратной записи (write-back).

    12.17. Замещения в кэше

    Если от ресурса получен новый кэшируемый отклик (см. разделы 13.9.2, 12.5, 12.6 и 12.8), в то время как какой-либо отклик для того же ресурса уже записан в кэш, кэшу следует использовать новый отклик для ответа на текущий запрос. Он может ввести его в память кэша и может, если он отвечает всем требованиям, использовать в качестве отклика для будущих запросов. Если он вводит новый отклик в память кэша, он должен следовать правилам из раздела 12.5.3.

    Замечание. Новый отклик, который имеет значение заголовка Date старше, чем кэшированные уже отклики, не должен заноситься в кэш.

    12.18. Списки предыстории

    Агенты пользователя часто имеют механизмы "исторического" управления, такие как кнопки "Back" и списки предыстории, которые могут использоваться для повторного отображения объекта, извлеченного ранее в процессе сессии. Механизмы предыстории и кэширования различны. В частности механизмы предыстории не должны пытаться показать семантически прозрачный вид текущего состояния ресурса.Скорее, механизм предыстории предназначен для того, чтобы в точности показать, что видел пользователь, когда ресурс был извлечен. По умолчанию время годности не приложимо к механизмам предыстории. Если объект все еще в памяти, механизм предыстории должен его отобразить, даже если время жизни объекта истекло и он объявлен непригодным, если только пользователь не сконфигурировал агента так, чтобы обновлять объекты, срок годности которых истек. Это не запрещает механизму предыстории сообщать пользователю, что рассматриваемый им объект устарел.

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


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