Опубликован: 28.09.2007 | Уровень: специалист | Доступ: платный
Лекция 7:

Гипертекстный протокол HTTP

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

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

messagebody = entitybody
        | <entitybody encoded as per Transfer-Encoding>

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

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

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

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

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

  1. Любое сообщение­отклик, которое не должно включать в себя тело сообщения (такое, как отклик 1xx, 204 и 304, а также любые отклики на запрос HEAD), всегда завершаются первой пустой строкой после полей заголовка, вне зависимости от присутствующих в сообщении полей заголовка объекта.
  2. Если присутствует поле заголовка Transfer-Encoding и указано, что использовано фрагментное ("chunked") транспортное кодирование, тогда длина тела определяется выбранной схемой кодирования.
  3. Если присутствует поле заголовка ContentLength, его значение в байтах и определяет длину тела сообщения.
  4. Если сообщение использует тип cреды multipart/byteranges, который является самоограничивающим, тогда он и определяет длину. Этот тип среды не должен использоваться, если отправитель не знает, может ли получатель разобрать его. Присутствие в запросе заголовка Range с множественными спецификаторами диапазона подразумевает, что клиент может разобрать отклики типа multipart/byteranges.
  5. Длина определяется сервером при закрытии связи. (Закрытие соединения не может применяться для обозначения конца тела запроса, так как это не оставит возможности для сервера послать отклик.)

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

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

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

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

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

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

generalheader   = Cache-Control
        | Connection
        | Date
        | Pragma
        | Transfer-Encoding
        | Upgrade
        | Via

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

Запрос

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

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

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

Request    Line = Method SP Request-URI SP HTTPVersion CRLF
Метод

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

Method  =   "OPTIONS"
      | "GET"
      | "HEAD"
      | "POST"
      | "PUT"
      | "DELETE"
      | "TRACE"
      | extensionmethod extensionmethod = token

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

Методы GET и HEAD должны поддерживаться всеми серверами общего назначения.

URI запроса

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

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 как 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, чтобы правильно интерпретировать запрос. Серверам рекомендуется откликаться на некорректный запрос Request-URI, соответствующим статусным кодом.

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

Правило "no rewrite" препятствует прокси изменить смысл запроса, когда исходный сервер некорректно использует незарезервированный URL символ для зарезервированных целей.

Следует остерегаться ситуации, когда некоторые предшествующие варианты проксисерверов HTTP/1.1 допускают перезапись Request-URI.

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

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

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

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

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

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

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

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

Requestheader  = Accept
        | AcceptCharset
        | AcceptEncoding
        | AcceptLanguage
        | Authorization
        | From
        | Host
        | If-Modified-Since
        | If-Match
        | If-None-Match
        | If-Range
        | If-Unmodified-Since
        | Max-Forwards
        | Proxy-Authorization
        | Range
        | Referer
        | User-Agent

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

Отклик

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

Response (отклик)  = StatusLine
          *( generalheader
          | responseheader
          | entityheader )
          CRLF
          [ messagebody ]
Статусная строка

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

StatusLine = HTTPVersion SP StatusCode SP ReasonPhrase CRLF
Статусный код и словесный комментарий

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

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

  • 1xx: Информационный — Запрос получен, процесс продолжается;
  • 2xx: Успех (Success) — Запрос успешно получен, понят и воспринят;
  • 3xx: Переадресация (Redirection) — Нужны дополнительные действия для завершения выполнения запроса;
  • 4xx: Ошибка клиента (Client Error) — Запрос содержит синтаксическую ошибку или не может быть выполнен;
  • 5xx: Ошибка сервера (Server Error) — Сервер не смог выполнить корректный запрос.

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

StatusCode  = "100"  ; Continue
      | "101"  ; Switching Protocols
      | "200"  ; OK
      | "201"  ; Created
      | "202"  ; Accepted
      | "203"  ; NonAuthoritative 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 Timeout
      | "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 Timeout
      | "505"  ; HTTP Version not supported
      | extensioncode
Extensioncode  = 3DIGIT
ReasonPhrase  = *

Статусные коды HTTP допускают расширение. HTTP приложения могут не понимать значение всех зарегистрированных статусных кодов, хотя такое понимание, очевидно, является желательным. Однако, приложения должны понимать класс любого статусного кода, который задается его первой цифрой, и воспринимать неузнанный отклик как x00. Неузнанный статусный отклик не должен заноситься в буфер. Например, если клиентом получен нераспознаваемый статусный код 431, он может предположить, что произошло что­то с запросом, и рассматривать отклик так, как если бы он равнялся 400. В таких случаях агентам пользователя рекомендуется предоставлять пользователю объект с откликом, который содержит текст, поясняющий причину создавшейся ситуации.

Евгений Виноградов
Евгений Виноградов

Прошел экстерном экзамен по курсу перепордготовки "Информационная безопасность". Хочу получить диплом, но не вижу где оплатить? Ну и соответственно , как с получением бумажного документа?

Илья Сидоркин
Илья Сидоркин

Добрый день! Подскажите пожалуйста как и когда получить диплом, после сдичи и оплаты?????

виктор виноградов
виктор виноградов
Россия, Курская область
Евгений Миловзоров
Евгений Миловзоров
Россия, Пенза, ПГУ, 2004