Гипертекстный протокол HTTP
Форматы даты/времени. Полная дата
HTTP приложения допускают три различных формата для представления метки времени и даты:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC-822, актуализировано в RFC-1123 Sunday, 06Nov94 08:49:37 GMT ; RFC-850, объявлено устаревшим в RFC-1036 Sun Nov 6 08:49:37 1994 ; ANSI C's asctime()
Первый формат предпочтительнее, как стандарт Интернет и представляет собой форму фиксированной длины, определенную RFC-1123. Второй формат используется достаточно широко, но базируется на устаревшем документе RFC-850 [7.12], формат даты не имеет 4 цифр года. Клиенты и серверы HTTP/1.1, которые анализируют дату, должны уметь работать со всеми тремя форматами (для совместимости с HTTP/1.0), хотя они должны сами генерировать время/дату согласно формату RFC-1123.
Получатели значений даты должны быть готовы принять коды, которые посланы не приложениями HTTP, что случается, когда данные поступают через прокси/порты или по почте в SMTP или NNTP-форматах.
Все метки времени/даты HTTP должны соответствовать времени по Гринвичу (GMT). Это указано в первых двух форматах путем включения строки "GMT" и должно предполагаться во всех прочих случаях.
HTTPdate = RFC-1123date | rRFC-850date | asctimedate RFC-1123date = wkday "," SP date1 SP time SP "GMT" RFC-850date = weekday "," SP date2 SP time SP "GMT" asctimedate = wkday SP date3 SP time SP 4DIGIT date1 = 2DIGIT SP month SP 4DIGIT ; day month year (\напр., 02 Jun 1982) date2 = 2DIGIT "" month "" 2DIGIT ; daymonthyear (напр., 02Jun82) date3 = month SP ( 2DIGIT | ( SP 1DIGIT )) ; month day (напр., 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"
HTTP требования для формата метки даты/времени применимы только для использования в рамках реализации самого протокола. Клиенты и серверы не требуют применения этих форматов для пользовательских презентаций, протоколирования запросов и т.д..
Интервалы времени в секундах
Некоторые поля заголовка HTTP допускают спецификацию значения времени в виде целого числа секунд, представленного в десятичной форме и равного времени с момента получения сообщения.
deltaseconds = 1*DIGIT
Наборы символов
HTTP использует то же определение термина "набор символов", что дано для MIME:
Термин "набор символов" относится к методу, который с помощью одной или более таблиц преобразует последовательность октетов в последовательность символов. Заметьте, что не требуется безусловного обратного преобразования, при этом не все символы могут быть доступны и одному и тому же символу может соответствовать более чем одна последовательность октетов. Это определение имеет целью допустить различные виды кодировок символов, от простых однотабличных, таких, как US-ASCII, до сложных — таблично переключаемых методов, используемых, например, в ISO 2022. Однако определение, связанное с набором символов MIME, должно полностью специфицировать схему соответствия октетов и символов. Применение внешних профайлов для определения схемы шифрования недопустимо.
Замечание. Здесь "набор символов" ближе к понятию "кодирование символов". Однако так как HTTP и MIME используют один и тот же регистр, важно, чтобы терминология также была идентичной.
Наборы символов HTTP идентифицируются лексемами, которые не чувствительны к использованию строчных или прописных букв. Полный набор лексем определен регистром наборов символов IANA [7.19].
charset = token
Несмотря на то, что HTTP позволяет использовать произвольную лексему в качестве значения charset, любая лексема, значение которой определено в рамках регистра набора символов IANA, должна представлять символьный набор, определенный этим регистром. Приложение должно ограничить использование символьных наборов только теми, которые определены регистром IANA.
Кодировки содержимого
Значения кодировки содержимого указывают на кодовое преобразование, которое было или может быть выполнено над объектом. Кодировки содержимого первоначально применены для того, чтобы иметь возможность архивировать документ или преобразовать его какимто другим способом без потери идентичности или информации. Часто объект запоминается закодированным, передается и только получателем декодируется.
contentcoding = token
Все значения кодировок содержимого не зависят от того, используются строчные или прописные символы. HTTP/1.1 реализует значения кодировок содержимого в полях заголовка AcceptEncoding и Content-Encoding. Хотя значение описывает кодирование содержимого, более важным является то, что оно определяет механизм декодирования.
Комитет по стандартным числам Интернет IANA (Internet Assigned Numbers Authority) выполняет функции регистра для значений лексем кодирования содержимого. Этот регистр хранит следующие лексемы:
gzip
Формат кодирования, реализуемый программой архивации файлов gzip (GNU zip), как описано в RFC-1952 [7.25]. Этот формат соответствует кодированию LempelZiv (LZ77) с 32 битным CRC.
compress
Формат кодирования, реализуемый стандартной программой UNIX для архивации файлов compress. Этот формат соответствует адаптивному методу кодирования LempelZivWelch (LZW).
Замечание. Использование имен программ для идентификации форматов кодирования нежелательно и будет в будущем заменено. Их использование здесь является следствием исторической практики. Для совместимости с предшествующими реализациями HTTP, приложения должны считать xgzip и xcompress эквивалентными gzip и compress соответственно.
deflate
Формат zlib определен документом RFC-1950 [7.31] в комбинации с механизмом сжатия deflate, описанным в RFC-1951 [7.29].
Транспортное кодирование
Значения транспортного кодирования используются для определения кодового преобразования, которому был подвергнут или желательно подвергнуть объект для того, чтобы гарантировать безопасную его транспортировку через сеть. Этот вид преобразования отличен от кодирования содержимого, так как относится к сообщению, а не к исходному объекту.
Transfercoding = "chunked" | transferextension Transferextension = token
Все значения транспортного кодирования не зависят от того, строчные или прописные буквы здесь применены. HTTP/1.1 несет значения транспортного кодирования в поле заголовка Transfer-Encoding.
Транспортные кодировки аналогичны используемым значениям ContentTransfer-Encoding MIME, которые были введены для обеспечения безопасной передачи двоичных данных через 7-битную транспортную среду. Однако безопасная транспортировка имеет другие аспекты в рамках 8-битного протокола передачи сообщений. В HTTP единственной небезопасной характеристикой тела сообщения является неопределенность его длины, или желание зашифровать данные при передаче по общему каналу.
Блочное кодирование фрагментов модифицирует тело сообщения для того, чтобы передать его в виде последовательности пакетов, каждый со своим индикатором размера, за которым следует опционная завершающая запись (footer), содержащая поля заголовка объекта. Это позволяет передать динамически сформированное содержимое, снабдив его необходимой информацией для получателя, который, в конце концов, сможет восстановить все сообщение.
Chunked Body = *chunk "0" CRLF footer CRLF Chunk = chunksize [ chunkext ] CRLF chunkdata CRLF Hexnozero = <HEX excluding "0"> Chunksize = hexnozero *HEX Chunkext = *( ";" chunkextname [ "=" chunkextvalue ] ) Chunkextname = token Chunkextval = token | quotedstring Chunkdata = chunksize(OCTET) Footer = *entityheader
Блочное кодирование фрагментов завершается пакетом нулевой длины, за которым следует завершающая запись и пустая строка. Назначение завершающей записи заключается в том, чтобы предоставить информацию о динамически сформированном объекте; приложения не должны пересылать поля заголовка в завершающей записи, кроме тех, которые специально оговорены, например, такие, как Content-MD5 или будущие расширения HTTP для цифровой подписи.
Все приложения HTTP/1.1 должны быть способны получать и декодировать получаемые фрагменты ("chunked"-кодирование) и должны игнорировать расширения транспортного кодирования, которые они не понимают. Сервер, получающий тело объекта с транспортной кодировкой, которую он не понимает, должен отослать отклик c кодом 501 (Unimplemented — не применимо) и закрыть соединение.
Сервер не должен применять транспортное кодирование при посылке данных клиенту HTTP/1.0.
Типы среды
HTTP использует типы среды Интернет (Internet Media Types) в полях заголовка Content-Type и Accept для того, чтобы обеспечить широкий и открытый обмен с самыми разными типами среды.
Mediatype = type "/" subtype *( ";" parameter ) Type = token Subtype = token
Параметры могут следовать за type/subtype в форме пар атрибут/значение.
Parameter = attribute "=" value Attribute = token value = token | quotedstring
Имена типа, субтипа и атрибутов параметра могут набираться как строчными, так и прописными буквами. Значения параметров могут быть и чувствительны к используемому регистру, в зависимости от семантики и имени параметра. Строчный пробел (LWS) не должен использоваться ни между типом и субтипом, ни между атрибутом и значением. Агенты пользователя, которые распознают тип среды, должны обрабатывать (или обеспечить обработку с использованием внешнего приложения для работы агента пользователя с типом/субтипом) параметры для типа MIME так, как это описано для данного типа/субтипа, и информировать пользователя о любых возникающих проблемах.
Некоторые старые приложения HTTP не узнают параметры типа среды. При посылке данных старому HTTPприложению программы должны использовать параметры типа среды, только когда они необходимы по описанию типа/субтипа.
Значения типа среды регистрируются IANA (Internet Assigned Number Authority). Процесс регистрации типа среды описан в RFC-2048 [7.17]. Использование незарегистрированных типов среды настоятельно не рекомендуется.
Канонизация и текст по умолчанию
Типы среды Интернет регистрируются каноническим образом. Вообще, тело объекта, передаваемого с помощью 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 используется с некоторыми типами среды, чтобы определить символьный набор. Когда параметр charset не задан отправителем явно, субтип среды text определяется так, что применяется символьный набор ISO-88591 по умолчанию. Данные с набором символов, отличным от ISO88591 или его субнабора, должны помечаться соответствующим значением charset.
Некоторые программы HTTP/1.0 интерпретируют заголовок Content-Type без параметра charset, неправильно предполагая, что "получатель должен решить сам, какой это набор". Отправители, желающие заблокировать такое поведение, могут включать параметр charset, даже когда charset равен ISO-88591, и должны делать так, когда известно, что это не запутает получателя.
К сожалению, некоторые старые HTTP/1.0 клиенты не обрабатывают корректно параметр charset. HTTP/1.1 получатели должны учитывать метку charset, присланную отправителем, и те агенты пользователя, которые умеют делать предположение относительно символьного набора, должны использовать символьный набор из поля contenttype, если они поддерживают этот набор, а не набор, предпочитаемый получателем.
Составные типы
MIME обеспечивает несколько составных типов — инкапсуляция одного или более объектов в общее тело сообщения. Все составные типы имеют общий синтаксис, как это определено в MIME [7.7], и должны включать граничный параметр, являющийся частью значения типа среды. Тело сообщения является само протокольным элементом и, следовательно, должно использовать только CRLF для обозначения разрывов строки. В отличие от MIME, завершающая часть любого составного cообщения должна быть пустой. HTTP приложения не должны передавать завершающую часть (даже если исходное составное сообщение содержит такую завершающую часть (эпилогподпись).
В HTTP составляющие части тела могут содержать поля заголовка, которые существенны для значения этих частей. Рекомендуется, чтобы поле заголовка ContentLocation было включено в часть тела каждого вложенного объекта, который может быть идентифицирован URL.
Вообще, рекомендуется, чтобы агент пользователя HTTP имел идентичное или схожее поведение с агентом пользователя MIME при получении составного типа. Если приложение получает неузнаваемый составной субтип, оно должно обрабатывать его также как multipart/mixed.
Тип multipart/formdata специально определен для переноса данных совместимого с методом обработки почтовых запросов, как это описано в RFC-1867 [7.15].
Лексемы (token) продукта
Лексемы продукта служат для того, чтобы позволить взаимодействующим приложениям идентифицировать себя с помощью имени и версии программного продукта. Большинство полей, использующих лексемы продукта, допускают также включение в список субпродуктов, которые образуют существенную часть приложения, их лексемы отделяются пробелом. По договоренности, продукты перечисляются в порядке их важности для идентификации приложения.
Product = token ["/" productversion] Productversion = token
Примеры:
User-Agent: CERNLineMode/2.15 libwww/2.17b3 Server: Apache/0.8.4
Лексемы продукта должны быть короткими, и, кроме того, использование их для оповещения или передачи маловажной информации абсолютно запрещено. Хотя любой символ лексемы может присутствовать в версии продукта, рекомендуется, чтобы эта лексема применялась только для идентификации версии (то есть, последовательные версии одного и того же продукта должны отличаться только в части версии продукта).
2.9. Значения качества (Quality values)
HTTP согласование параметров содержимого использует короткие числа с плавающей запятой для указания относительной важности (веса) различных параметров. Вес нормализуется на истинное число в диапазоне 0 1, где 0 равен минимальному, а 1 — максимальному значению. Приложения HTTP/1.1 не должны генерировать более трех чисел после запятой. Рекомендуется, чтобы конфигурация пользователя для этих значений удовлетворяла тем же ограничениям.
qvalue = ( "0" [ "." 0*3DIGIT ] ) | ( "1" [ "." 0*3("0") ] )
Quality values (значения качества) является неверным названием, так как эти значения в большей степени отражают относительную деградацию желательного качества.
Языковые метки
Языковая метка идентифицирует естественный язык. Компьютерные языки в этот перечень не входят. HTTP использует языковые метки в полях AcceptLanguage и ContentLanguage.
Синтаксис и регистр языковых меток HTTP тот же, что и определенный в RFC-1766 [7.1]. Языковая метка содержит одну или более частей: первичная языковая метка и последовательность субметок, которая может и отсутствовать.
languagetag = primarytag *( "" subtag ) primarytag = 1*8ALPHA subtag = 1*8ALPHA
Пробел недопустим в метке, применение строчных и прописных букв не играет никакой роли. Перечень языковых меток контролируется IANA. Ниже приведены примеры языковых меток:
en, enUS, encockney, icherokee, xpiglatin
где любые две буквы первичной метки представляют собой языковую аббревиатуру ISO 639 и две буквы исходной субметки соответствуют коду страны ISO 3166 (последние три метки не являются зарегистрированными; все, кроме последней, могут быть зарегистрированы в будущем).
Метки объектов
Метки объектов служат для сравнения двух или более объектов из одного и того же запрошенного ресурса. HTTP/1.1 использует метки объектов в полях заголовков ETag, If-Match, If-None-Match и If-Range. Метки объекта состоят из строк, заключенных в кавычки, перед ней может размещаться индикатор слабости.
entitytag = [ weak ] opaquetag Weak = "W/" opaquetag = quotedstring
"Сильная метка объекта" (strong entity tag) может принадлежать двум объектам ресурса, если они эквивалентны на октетном уровне.
"Слабая метка объекта" (weak entity tag) отмечается префиксом "W/", она может относиться к двум объектам ресурса, только если объекты эквивалентны и могут быть взаимозаменяемы. Слабая метка объекта может применяться для "слабого" сравнения.
Метка объекта должна быть уникальной для всех версий всех объектов, сопряженных с конкретным ресурсом. Значение данной метки объекта может использоваться для объектов, полученных в результате запросов для различных URI без использования данных об эквивалентности этих объектов.
Структурные единицы
HTTP/1.1 позволяет клиенту запросить только часть объекта (диапазон). HTTP/1.1 использует структурные единицы, определяющие выделение части объекта, в полях заголовка Range и ContentRange. Объект может быть разбит на фрагменты с использованием различных структурных единиц.
rangeunit = bytesunit | otherrangeunit bytesunit = "bytes" otherrangeunit = token
Единственной структурной единицей, определенной в HTTP/1.1, является bytes. HTTP/1.1 реализации могут игнорировать диапазоны, специфицированные с использованием других структурных единиц. Стандарт HTTP/1.1 сконструирован так, чтобы позволить реализацию приложений, которые не зависят от знания диапазонов.
HTTP сообщение. Типы сообщений
Сообщения HTTP включают в себя запросы клиента к серверу и отклики сервера клиенту.
HTTPmessage = Request | Response ; HTTP/1.1 messages
Сообщения запрос и отклик используют общий формат сообщений RFC-822 [7.9] для передачи объектов (поле данных сообщения). Оба типа сообщений состоят из стартовой строки, одного или более полей заголовка (также известные как "заголовки"), пустой строки (то есть, строка, содержащая CRLF ), отмечающей конец полей заголовка, а также опционного тела сообщения.
genericmessage = startline *messageheader CRLF [ messagebody ] startline = RequestLine | StatusLine
В интересах надежности рекомендуется серверам игнорировать любые пустые строки, полученные, когда ожидается RequestLine (строка запроса). Другими словами, если сервер читает протокольный поток в начале сообщения и получает сначала CRLF, он должен игнорировать CRLF.
Определенные некорректные реализации HTTP/1.0 клиентов генерируют дополнительные CRLF после запроса POST. Клиент HTTP/1.1 не должен посылать CRLF до или после запроса.
Заголовки сообщений
Поля заголовка HTTP, которые включают в себя общие поля заголовка, заголовка запроса, заголовка отклика и заголовка объекта, следуют тому же общему формату, что дан в разделе 3.1 RFC-822 [7.9]. Каждое поле заголовка состоит из имени, за которым следует двоеточие (":"), и поля значения. Поля имен безразличны в отношении использования строчных и прописных букв. Поле значения может начинаться с любого числа LWS, хотя один SP предпочтительнее. Поля заголовка могут занимать несколько строк, каждая новая строка должна открываться, по крайней мере, одним SP или HT. Рекомендуется, чтобы приложения следовали общему формату, если они создаются конструкциями HTTP, так как могут существовать некоторые реализации, которые не могут воспринимать ничего, кроме общих форматов.
Messageheader = fieldname ":" [ fieldvalue ] CRLF fieldname = token fieldvalue = *( fieldcontent | LWS )
fieldcontent = <OCTET'ы образуют значения поля и состоят из *TEXT или комбинаций лексем, tspecials и закавыченных строк>
Порядок, в котором приходят поля заголовка с отличающимися именами, не имеет значения. Однако хорошей практикой считается посылка сначала поля общего заголовка, за которым следует заголовок запроса или отклика, а в заключение поля заголовка объекта.
Множественные поля заголовка сообщения с идентичными именами могут присутствовать тогда и только тогда, когда значение поля определяется как список из элементов, разделенных запятыми [то есть, #(значения)]. Должна быть предусмотрена возможность объединять множественные поля заголовка в одну пару "имя_поля: значение_поля", без изменения семантики сообщения, путем добавления каждой последующей пары полезначение, отделенных друг от друга запятыми. Порядок, в котором следуют поля заголовка с идентичными именами, влияет на последующую интерпретацию значения комбинированного поля, по этой причине проксисервер не должен менять порядок значений этих полей при переадресации сообщения.