Приложение 5.
Протокол HTTP

Введение

Протокол HTTP (Hypertext Transfer Protocol, протокол передачи гипертекстов) — это протокол прикладного уровня для распределенных гипертекстовых информационных систем. Помимо передачи гипертекстов он может применяться и в других областях, таких, как серверы имен и распределенные системы управления объектами, но для наших целей важно то, что на этом протоколе с момента своего появления в 1990 г. и по сей день базируется World Wide Web. Приведенное ниже краткое его описание основано на спецификации HTTP/1.1 (RFC 2616 Внешняя ссылка, июнь 1999 г.). Место HTTP в иерархии протоколов Сети показано на рисунке.

Иерархия протоколов Интернета

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

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

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

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

Сообщения HTTP

Сообщения HTTP состоят из запросов клиента к серверу и откликов сервера к клиенту. Оба типа сообщений состоят из:

  • стартовой строки, определяющей тип сообщения;
  • нуля или более полей заголовка (кратко называемых просто заголовки);
  • пустой строки, содержащей только символы CR LF и указывающей на конец заголовков;
  • необязательного тела сообщения.

Каждое из полей заголовков имеет формат

имя_поля ":" значение_поля

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

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

имя_поля ":" значение1 "," значение2

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

Поля заголовка

Таблица П5.1. Общие поля заголовка
Поле Описание
Cache-Control Задает директивы управления механизмами кэширования. Пример:
Cache-Control: no-cache.
Connection Задает параметры конкретного соединения. Пример:
Connection: close.
Date Дата и время посылки данного сообщения. Пример:
Date: Tue, 15 Nov 1999 08:12:31 GMT.
Pragma Используется для задания директив, зависящих от реализации. Пример:
Pragma: no-cache.
Trailer Указывает, какие поля заголовка прицеплены к телу сообщения и закодированы согласно Transfer-Encoding. См. поле TE. Пример:
Trailer: Authorization.
Transfer-Encoding Задает способ кодировки тела сообщения. Пример:
Transfer-Encoding: chunked.
Upgrade Указывает, какие дополнительные протоколы поддерживает клиент или на какой протокол переключился сервер. Пример:
Upgrade: SHTTP/1.3, IRC/6.9, RTA/x11.
Via Используется шлюзами и прокси-серверами для задания промежуточных протоколов и получателей. Пример:
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1).
Warning Содержит дополнительную информацию о текущем состоянии или о сообщении. Пример:
Warning: 112 ricky Disconnected operation.
Таблица П5.2. Поля заголовка запроса
Поле Описание
Accept Задает типы файлов MIME, приемлемые в отклике. Пример:
Accept: text/*, text/html.
Accept-Charset Задает кодировки символов, приемлемые в отклике. Пример:
Accept-Charset: iso-8859-5, unicode-1-1.
Accept-Encoding Задает кодировки содержимого, приемлемые в отклике. Пример:
Accept-Encoding: compress, gzip.
Accept-Language Задает естественные языки, приемлемые в отклике. Пример:
Accept-Language: ru, en-us, en.
Authorization Задает имя и пароль пользователя для авторизации доступа к ресурсу согласно RFC 2617 Внешняя ссылка.
Expect Указывет, что клиент ожидает от сервера определенной реакции. Пример:
Expect: 100-continue.
From Задает адрес электронной почты администратора клиента. Пример:
From: webmaster@w3.org.
Host Задает имя и, возможно, порт хост-компьютера, на котором расположен запрашиваемый ресурс.Пример:
Host: www.mysite.com.
If-Match Используется в условных методах: запрошенный ресурс передается, только если он содержит один из заданных тегов. Пример:
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz".
If-Modified-Since Используется в условных методах: запрошенный ресурс передается, только если он был изменен после указанной даты. Пример:
If-Modified-Since: Sat, 29 Oct 1999 19:43:31 GMT.
If-None-Match Используется в условных методах: запрошенный ресурс передается, только если он не содержит ни одного из заданных тегов. Пример:
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz".
If-Range Используется в условных методах: запрошенный ресурс передается целиком, если он был изменен после указанной даты: иначе передается недостающая часть ресурса. Пример:
If-Range: Sat, 29 Oct 1999 19:43:31 GMT.
If-Unmodified-Since Используется в условных методах: запрошенный ресурс передается, только если он не был изменен после указанной даты. Пример:
If-Unmodified-Since: Sat, 29 Oct 1999 19:43:31 GMT.
Max-Forwards Задает максимальное количество шлюзов и прокси-серверов, которые могут быть использованы для передачи сообщения следующему серверу. Пример:
Max-Forwards: 5.
Proxy-Authorization Задает имя и пароль пользователя для авторизации доступа к прокси-серверу согласно RFC 2617 Внешняя ссылка.
Range Задает диапазон номеров байтов в теле сообщения. Пример:
Range: bytes=0-499.
Referer Задает URI ресурса, из которого был получен URI запроса. Позволяет серверу создавать списки обратных ссылок и отслеживать устаревшие ссылки. Пример:
Referer: http://www.mysite.com/index.html.
TE Указывает, какие кодировки расширений принимаются в отклике, и принимаются ли кодированные прицепные поля. Пример:
TE: trailers, deflate.
User-Agent Информация об обозревателе, пославшем запрос. Пример:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3.
Таблица П5.3. Поля заголовка отклика
Поле Описание
Accept-Ranges Указывает, может ли сервер передавать диапазоны байтов. Пример:
Accept-Ranges: none.
Age Возвращает время в секундах, прошедшее с генерации отклика исходным сервером. Пример:
Age: 230.
ETag Содержит тег текущего сообщения. Пример:
ETag: "xyzzy".
Location Возвращает полный URI запрошенного ресурса. Пример:
Location: http://www.mysite.com/index.html.
Proxy-Authenticate Сообщает, что прокси-сервер требует авторизации, и возвращает схему авторизации согласно RFC 2617 Внешняя ссылка.
Retry-After Сообщает, как долго еще ресурс будет недоступен. Пример:
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT.
Server Содержит информацию о программном обеспечении сервера, пославшего отклик. Пример:
Server: CERN/3.0 libwww/2.17.
Vary Содержит набор полей заголовка запроса, который полностью определяет возможность использования кэша. Пример:
Vary: *.
WWW-Authenticate Сообщает, что ресурс требует авторизации, и возвращает схему авторизации согласно RFC 2617 Внешняя ссылка.
Таблица П5.4. Поля заголовка тела
Поле Описание
Allow Содержит список методов, поддерживаемых запрошенным ресурсом. Пример:
Allow: GET, HEAD, PUT.
Content-Encoding Задает способ кодирования тела сообщения. Пример:
Content-Encoding: gzip.
Content-Language Задает естественный язык, на котором написано тело сообщения. Пример:
Content-Language: ru.
Content-Length Задает размер тела в байтах. Пример:
Content-Length: 3495.
Content-Location Содержит URI тела сообщения, когда он отличен от URI запроса. Пример:
Content-Location: images/1234.gif.
Content-MD5 Содержит контрольное значение MD5, используемое для проверки целостности тела сообщения согласно RFC 1864 Внешняя ссылка.
Content-Range Содержит диапазон байтов в теле сообщения. Пример:
Content-Range: bytes 0-499/1234.
Content-Type Содержит тип MIME тела сообщения. Пример:
Content-Type: text/html; charset=ISO-8859-4.
Expires Дата и время, после которых содержание отклика становится устаревшим. Пример:
Expires: Thu, 01 Dec 1999 16:00:00 GMT.
Last-Modified Дата и время последней модификации передаваемого ресурса. Пример:
Last-Modified: Tue, 15 Nov 1999 12:45:26 GMT.

Типы запросов

Строка запроса имеет вид

метод " " URI_запроса " " версия_HHTP CR LF

Здесь метод — это название типа запроса, URI_запроса — это либо URI запрашиваемого ресурса, либо символ "*" в тех случаях, когда запрос не связан с конкретным ресурсом, а версия_HHTP выглядит так:

"HTTP/" цифра "." цифра

Типичные примеры строк запроса:

GET http://www.mysite.com/index.html HTTP/1.1
OPTIONS * HTTP/1.1

Запрос OPTIONS

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

Если URI запроса задано символом "*", то запрос относится к серверу, а не к конкретному ресурсу, и позволяет запросить возможности сервера.

Запрос GET

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

Этот метод является условным, если в его заголовке заданы поля If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match или If-Range. Условный метод отличается тем, что запрошенный ресурс будет возвращен только в том случае, когда он удовлетворяет заданному условию.

Запрос HEAD

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

Запрос POST

Метод POST используется в следующих случаях:

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

Суть данного метода состоит в том, что тело запроса передается серверу, и тот интерпретирует его в зависимости от URI запроса (обычно это адрес программы, которая должна обработать данные, содержащиеся в теле запроса). Например, если URI запроса содержит имя CGI-сценария, то этот сценарий будет запущен на сервере и в качестве параметра ему будет передано тело запроса POST.

Запрос PUT

Метод PUT используется для создания нового ресурса с заданным в запросе URI. Если ресурс с таким URI уже существует, то тело запроса рассматривается как его обновленная версия.

Запрос DELETE

Метод DELETE используется для удаления ресурса, имеющего заданный URI.

Запрос TRACE

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

Запрос CONNECT

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

Формат отклика

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

строка_состояния
заголовки
CR LF
тело_сообщения

где строка_состояния имеет вид

версия_HTTP " " код_состояния " " описание CR LF

Здесь версия_HTTP имеет тот же формат, что и в запросе, коды состояния описаны ниже, а описание — это строка, содержащая краткое текстовое описание кода_состояния.

Типичный пример отклика, возвращающего запрошенный HTML-документ:

HTTP/1.1 200 OK
Date: Wednesday, 02-Feb-00 23:04:12 GMT
Server: NCSA/1.3
MIME-version: 1.0
Last-modified: Monday, 15-Nov-99 23:33:16 GMT
Content-type: text/html
Content-length: 2345
 пустая строка
<HTML><HEAD>…</HTML>

Коды состояния

Код состояния — это целое число из трех цифр, которое указывает на результат выполнения запроса. Первая цифра этого числа определяет класс отклика:

  1. Информационные сообщения (запрос получен, идет его обработка).
  2. Успех (запрос был получен, понят и понят сервером).
  3. Перенаправление (для завершения запроса необходимы дальнейшие действия обозревателя).
  4. Ошибка клиента (запрос неверно составлен или не может быть выполнен).
  5. Ошибка сервера (сервер не смог исполнить, по-видимому, верный запрос).

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

Таблица П5.5. Коды состояния HTTP
Код Название Описание
100 Продолжайте Клиент должен продолжать передачу запроса. Уже переданная им часть запроса получена и не была отвергнута сервером.
101 Переключение протоколов Сервер предлагает изменить протокол на указанный в поле заголовка отклика Update. Обычно это предложение о переходе на более новую версию HTTP.
110 Отклик мог устареть Отклик является устаревшим (используется в заголовке Warning).
111 Обновление не удалось Отклик от кэша не является свежим, т. к. попытка обновить его закончилась неудачей (используется в заголовке Warning).
112 Разрыв соединения Кэш был умышленно отсоединен от остальной сети на некоторое время (используется в заголовке Warning).
113 Эвристическое устаревание Кэш эвристически выбрал период обновления, больший 24 часов, и возраст отклика более 24 часов (используется в заголовке Warning).
199 Различные предупреждения Дополнительные предупреждения, не содержащиеся в данном списке (используется в заголовке Warning).
200 OK Запрос был успешно обработан. Содержимое отклика зависит от типа запроса.
201 Создано Запрос был успешно обработан и в результате был создан новый ресурс. Его URI указан в поле заголовка отклика Location.
202 Принято Запрос был принят и его обработка началась другим асинхронным процессом, поэтому сервер не сможет сообщить о ее завершении.
203 Неавторитетная информация Возвращаемая метаинформация получена не от сервера ее происхождения, а из локальной копии.
204 Нет содержимого Сервер выполнил запрос, но ему нечего возвращать клиенту. Обозреватель не должен изменять отображение документа.
205 Сброс содержимого Сервер выполнил запрос, и обозреватель должен сбросить отображение документа.
206 Частичное содержимое Сервер выполнил частичный запрос GET для ресурса.
214 Применено преобразование Применено преобразование, изменившее кодировку или тип MIME отклика (используется в заголовке Warning).
299 Различные настойчивые предупреждения Дополнительные предупреждения, не содержащиеся в данном списке (используется в заголовке Warning).
300 Несколько вариантов Запрошенный ресурс имеет несколько представлений, и клиент должен выбрать одно из них.
301 Ресурс перенесен Запрошенный ресурс сменил свой URI. Его новый URI указан в поле заголовка отклика Location.
302 Найдено Запрошенный ресурс временно сменил свой URI.
303 Смотри другое Отклик на данный запрос может быть найден под другим URI, указанным в поле заголовка отклика Location.
304 Не изменено Клиент выполнил условный запрос GET, доступ разрешен, но документ не был изменен.
305 Используйте прокси Доступ к запрошенному ресурсу возможен только через прокси-сервер, указанный в поле заголовка отклика Location.
306 зарезервирован  
307 Временное перенаправление Запрошенный ресурс временно находится под другим URI, указанном в поле заголовка отклика Location.
400 Неверный запрос Запрос не был понят сервером из-за его неверного синтаксиса.
401 Нет права доступа Запрос требует авторизации доступа, тип которой указан в поле заголовка отклика WWW-Authenticate.
402 Требуется платеж Зарезервировано для следующих версий HTTP.
403 Запрещено Сервер понял запрос, но отказался его выполнять.
404 Не найдено Ресурс, заданный в URI запроса, не найден.
405 Недопустимый метод Данный тип запроса не применим к ресурсу, заданному в URI запроса.
406 Неприемлемо Ресурс, заданный в URI запроса, может генерировать только отклики, не приемлемые для клиента.
407 Прокси требует авторизации доступа Прокси-сервер требует авторизации доступа, тип которой указан в поле заголовка отклика Proxy-Authenticate.
408 Таймаут запроса Клиент не послан ни одного запроса в течение отведенного ему интервала.
409 Конфликт Запрос не может быть выполнен из-за конфликта с текущим состоянием ресурса.
410 Ресурс исчез Запрошенного ресурса больше нет на сервере, и сервер не знает его нового URI.
411 Требуется длина запроса В запросе не задано поле заголовка Content-Length.
412 Условие ложно Условие, заданное в заголовке условного запроса, не может быть выполнено.
413 Слишком длинное тело запроса Тело запроса длиннее, чем допускает сервер.
414 Слишком длинное URI запроса URI запроса длиннее, чем допускает сервер.
415 Не поддерживаемый тип устройства Формат тела запроса не поддерживается данным ресурсом для данного типа запроса.
416 Запрошенный диапазон пуст Запрошенный ресурс не содержит значений в диапазоне, заданном в поле заголовка запроса Range.
417 Предположение не оправдалось Предположение, указанное в поле заголовка запроса Expect, отвергнуто сервером.
500 Внутренняя ошибка сервера Запрос не исполнен из-за неожиданной ошибки сервера.
501 Не реализовано Сервер не поддерживает данный тип запросов.
502 Плохой шлюз Сервер, выступающий в роли шлюза или прокси-сервера, получил неверный отклик от следующего сервера.
503 Служба недоступна Сервер временно не может исполнить запрос из-за перегрузки.
504 Таймаут шлюза Сервер, выступающий в роли шлюза или прокси-сервера, не получил своевременного отклика от следующего сервера.
505 Версия HTTP не поддерживается Сервер не поддерживает версию HTTP, указанную в заголовке запроса.