HTTP (Hypertext Transfer Protocol)

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 19:12, 20 июля 2016.
HTTP
Уровень (по модели OSI): Прикладной
Семейство: стек протоколов TCP/IP
Порт/ID: 80/TCP
Спецификация: RFC 1945, RFC 2616
Основные реализации (клиенты): Веб-браузеры, например Internet Explorer, Mozilla Firefox, Opera, Google Chrome и др.
Основные реализации (серверы): Apache HTTP Server
Вступил в силу с: 1992

HTTP (англ. HyperText Transfer Protocol — «протокол передачи гипертекста») — сетевой протокол прикладного уровня передачи данных. Протокол основан на технологии "клиент-сервер", то есть предполагается существование потребителей (клиентов), которые инициируют соединение и посылают запрос, и поставщиков (серверов), которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом.

HTTP используется в других протоколах прикладного уровня, а также для передачи с сервера на клиент любых объектов: картинок, скриптов, CSS-файлов, файлов данных. Также он работает и в обратную сторону — для заливки на сервер файлов, отправки форм и т.п. AJAX-приложения также, очевидно, общаются с сервером по HTTP. Иногда HTTP используется и для более специфических вещей, например, для управления содержимым сервера по протоколу WebDAV, XML-RPC, WebDAV.

Существуют протоколы, аналогичные HTTP, такие как FTP и SMTP. Чтобы идентифицировать ресурсы HTTP протокол использует глобальные URL. HTTP не сохраняет своего состояния между парами "запрос-ответ". Компоненты HTTP могут сохранять информацию. Например, со стороны клиента сохраняются "куки", а на стороне сервера "сессии". Браузер, в свою очередь, может отслеживать задержки ответов, а сервер хранит IP-адреса запросов клиентов.

История

HTTP/0.9
HTTP был предложен в марте 1991 года Бернерс-Ли,Тимом Бернерсом-Ли, работавшим тогда в CERN, как механизм для доступа к документам в Интернете и облегчения навигации посредством использования гипертекста. Самая ранняя версия протокола HTTP/0.9 была впервые опубликована в январе 1992г. (хотя реализация датируется 1990 годом). Спецификация протокола привела к упорядочению правил взаимодействия между клиентами и серверами HTTP, а также чёткому разделению функций между этими двумя компонентами. Были задокументированы основные синтаксические и семантические положения.
HTTP/1.0
В мае 1996 года для практической реализации HTTP был выпущен информационный документ RFC 1945, что послужило основой для реализации большинства компонентов HTTP/1.0.
HTTP/1.1
Текущая версия протокола, принята в июне 1999 года. Впервые спецификация HTTP/1.1 была опубликована в январе 1997. Также разъяснено допустимое поведение клиента (браузера), сервера и прокси-серверов в некоторых сомнительных ситуациях. То есть версия 1.1 появилась всё-таки в 1997 году. Новым в этой версии был режим «постоянного соединения»: TCP-соединение может оставаться открытым после отправки ответа на запрос, что позволяет посылать несколько запросов за одно соединение. Клиент теперь обязан посылать информацию об имени хоста, к которому он обращается, что сделало возможной более простую организацию виртуального хостинга.
HTTP/2 
11 февраля 2015 года опубликованы финальные версии черновика следующей версии протокола. В отличие от предыдущих версий, протокол HTTP/2 является бинарным. Среди ключевых особенностей мультиплексирование запросов, расстановка приоритетов для запросов, сжатия заголовков, загрузка нескольких элементов параллельно, посредством одного TCP соединения, поддержка проактивных push-уведомлений со стороны сервера.

Параметры протокола

HTTP сообщение

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

HTTP-message = Request | Response ; HTTP/1.1 messages
Взаимодействие клиента (UA), кэша и исходного сервера в протоколе HTTP

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

generic-message = start-line
*message-header
CRLF
[ message-body ]
start-line = Request-Line | Status-Line

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

Методы

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

Каждый сервер обязан поддерживать как минимум методы GET и HEAD. Если сервер не распознал указанный клиентом метод, то он должен вернуть статус 501 (Not Implemented). Если серверу метод известен, но он неприменим к конкретному ресурсу, то возвращается сообщение с кодом 405 (Method Not Allowed). В обоих случаях серверу следует включить в сообщение ответа заголовок Allow со списком поддерживаемых методов.

Кроме методов GET и HEAD, часто применяется метод POST.

GET

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

HEAD

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

PUT

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

POST

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

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

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

DELETE

Метод DELETE требует, чтобы исходный сервер уничтожил ресурс, идентифицируемый Request-URI.

TRACE

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

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

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

Диалог HTTP

Запрос клиента:

 
#GET|GET /wiki/''страница'' HTTP/1.1
 Host: ru.wikipedia.org
 User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
 Accept: text/html
 Connection: close
 ''(пустая строка)''
  

Ответ сервера:

 
HTTP/1.1 200 OK
 Date: Wed, 11 Feb 2009 11:20:59 GMT
 Server: Apache
 X-Powered-By: PHP/5.2.4-2ubuntu5wm1
 Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT
 Content-Language: ru
 Content-Type: text/html; charset=utf-8
 Content-Length: 1234
 Connection: close
 ''(пустая строка)''
 ''(далее следует запрошенная страница в HTML)''В настоящее время выделено пять классов кодов состояния.
Список кодов состояния HTTP#1xx|1xx Informational («Информационный»)

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

Список кодов состояния HTTP#2xx|2xx Success («Успех»)

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

Список кодов состояния HTTP#3xx|3xx Redirection («Перенаправление»)

Коды класса 3xx сообщают клиенту что для успешного выполнения операции необходимо сделать другой запрос (как правило по другому URI). Из данного класса пять кодов Список кодов состояния #301|301, Список кодов состоянияHTTP#302|302, Список кодов состоянияHTTP#303|303, Список кодов состоянияHTTP#305|305 и Список кодов состояния #307|307 относятся непосредственно к перенаправлениям (редирект). Адрес, по которому клиенту следует произвести запрос, сервер указывает в заголовке Location. При этом допускается использование фрагментов в целевом URI.

Список кодов состояния HTTP#4xx|4xx Client Error («Ошибка клиента»)

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

Список кодов состояния HTTP#5xx|5xx Server Error («Ошибка сервера»)

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

Код Ошибка Описание
300 Множественный выбор Затребованный URL обозначает более одного ресурса, и робот не смог однозначно определить, к какой странице URL относится (получен код 300 Multiple Choices).
301 Ресурс перемещен навсегда Документ уже не используется сервером, а ссылка перенаправляет на другую страницу (получен код 301 Moved Permanently).
307 Временное перенаправление Затребованный ресурс был временно переведен на другой адрес, который необходимо прописать в Location (получен код 307 Temporary Redirect).
400 Неверный запрос Запрос не может быть понят сервером из-за некорректного синтаксиса (получен код 400 Bad Request).
403 Доступ к ресурсу запрещен Доступ к документу запрещен (получен код 403 Forbidden). Если вы хотите, чтобы страница индексировалась, необходимо разрешить доступ к ней.
404 Ресурс не найден Документ не существует (получен код 404 Not Found).
410 Ресурс недоступен Затребованный ресурс был окончательно удален с сайта (получен код 410 Gone).
412 Сбой при обработке предварительного условия При проверке на сервере одного или более полей заголовка запроса обнаружено несоответствие (сбой или ошибка при обработке предварительного условия).
417 Сбой при ожидании Сервер отказывается обрабатывать запрос, потому что значение поля Expect в заголовке запроса не соответствует ожиданиям (получен код 417 Expectation Failed).
423 Заблокировано Сервер отказывается обработать запрос, так как один из требуемых ресурсов заблокирован (получен код 423 Locke).
500 Внутренняя ошибка сервера Сервер столкнулся с непредвиденным условием, которое не позволяет ему выполнить запрос (получен код 500 Internal Server Error).
502 Ошибка шлюза Сервер, действуя в качестве шлюза или прокси-сервера, получил недопустимый ответ от следующего сервера в цепочке запросов, к которому обратился при попытке выполнить запрос
505 Версия HTTP не поддерживается Сервер не поддерживает или отказывается поддерживать версию HTTP-протокола, которая используется в сообщении запроса робота (получен код 505 HTTP Version Not Supported).

Структура протокола

Запрос

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

Request            = Request-Line	
                          *( generalheader	
                          | requestheader	
                          | entityheader )	
                          CRLF	
                          [ message body ]

Отклик

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

Response	= Status-Line	; Раздел 5.1
*( general-header	; Раздел 3.5
| response-header	; Раздел 5.2
| entity-header )	; Раздел 6.1
CRLF	
[ message-body ]	; Раздел 6.2

Отправив HTTP-запрос серверу, клиент ожидает ответа. HTTP-ответ выглядит в целом аналогично запросу: статусная строка, список заголовков и тело ответа.

HTTP/1.1 200 OK
Server: nginx/0.5.35
Date: Tue, 22 Apr 2008 10:18:08 GMT
Content-Type: text/plain; charset=windows-1251
Connection: close
Last-Modified: Fri, 30 Nov 2007 12:46:53 GMT
ETag: ``27e74f-43-4750063d''
Accept-Ranges: bytes
Content-Length: 34

User-agent: *
Disallow: /people

Объект и соединение

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

Структура ресурса и объекта

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

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

Клиенты

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

Исходные серверы

Apache HTTP ServerApache, Internet Information Services (IIS), nginx, Google Web Server, lighttpd.

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

Squid, UserGate, Multiproxy, Naviscope, nginx.

Оптимизация

Оптимизация с помощью HTTP keep-alive

Протокол HTTP работает поверх протокола TCP («Transmission Control Protocol»). TCP — это надёжный протокол двусторонней передачи потока данных. TCP работает, пересылая пакеты данных от клиента к серверу и обратно. TCP-пакет состоит из заголовка и данных. В заголовке указаны, помимо прочего, IP-адреса клиента и сервера, номера TCP-портов, используемых на клиенте и сервере, и набор флагов. Для HTTP на сервере обычно используется стандартный TCP-порт номер 80.

TCP-соединение между клиентом и сервером устанавливается с помощью классического «TCP three-way handshake». Сначала клиент посылает серверу пакет с флагом SYN. В ответ сервер посылает пакет с флагами SYN+ACK. Наконец, клиент посылает ещё один пакет, с флагом ACK и с этой минуты соединение считается установленным, и клиент может посылать свои данные, в нашем случае — HTTP-запрос. Понятно, что если десяток тысяч браузеров установит с сервером keep-alive соединение, то они достаточно быстро исчерпают его ресурсы. Поэтому во всех серверах есть конфигурируемый тайм-аут, по истечении которого keep-alive соединение разрывается, если на нём не было никакой активности.

Клиент может запросить разрыв соединения после ответа, передав в запросе заголовок Connection: close. Аналогично, сервер может сообщить в ответе, что не желает поддерживать keep-alive соединение, передав точно такой же заголовок: Connection: close. Вообще говоря, все эти расшаркивания с взаимным уведомлением, строго говоря, не налагают никаких обязанностей. И сервер, и клиент должны быть полностью готовы к тому, что соединение прервётся в любой момент времени по инициативе другой стороны без каких-либо уведомлений.

Для того, чтобы соблюсти целостность keep-alive соединения, сервер должен знать длину ответа. Самый простой способ — указать её в заголовке Content-Length. Если длина ответа не указана обработчиком, то сервер вынужден перед отправкой ответа установить заголовок Connection: close и закрыть соединение со своей стороны после отправки ответа.

Оптимизация с помощью компрессии

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

Способность принимать компрессированное содержимое клиент анонсирует серверу с помощью заголовка Accept-Encoding: gzip. Если сервер настроен на сжатие соответствующего контента, то он может добавить заголовок ответа Content-Encoding: gzip (не путать с Transfer-Encoding) и отправить клиенту сжатое содержимое.

Оптимизация с помощью HTTP-pipelining

Когда мы делаем серию запросов и ответов в рамках одного keep-alive соединения, важную роль в производительности играет время задержки (latency) между запросом и ответом. Задержка может быть вызвана как высокой задержкой на канале, так и большим временем обработки запросов на сервере. Перед посылкой очередного запроса мы должны дождаться завершения обработки следующего. Чтобы справиться с этой проблемой, может использоваться технология HTTP-pipelining.

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

Обеспечение безопасности

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

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

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

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

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

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

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

Ccылки

  1. Материал из Википедии — свободной энциклопедии - HTTP - Режим доступа [1]
  2. Протокол HTTP [2]
  3. 4.5.6.1 Гипертекстный протокол HTTP [3]
  4. Справочник по кодам статуса HTTP [4]
  5. HTTP - HyperText Transfer Protocol [5]