Что нужно знать про HTTP протокол веб-разработчику. Правила HTTP протокола
.) Именно благодаря возможности указания способа кодирования сообщения клиент и сервер могут обмениваться двоичными данными, хотя данный протокол является текстовым.
Прокси-серверы
История развития
HTTP/0.9
Кроме обычного метода GET , различают ещё и . Условные запросы GET содержат заголовки If-Modified-Since , If-Match , If-Range и подобные. Частичные GET содержат в запросе Range . Порядок выполнения подобных запросов определён стандартами отдельно.
HEAD
Аналогичен методу GET , за исключением того, что в ответе сервера отсутствует тело. Запрос HEAD обычно применяется для извлечения метаданных , проверки наличия ресурса (валидация URL) и чтобы узнать, не изменился ли он с момента последнего обращения.
Заголовки ответа могут кэшироваться. При несовпадении метаданных ресурса с соответствующей информацией в кэше копия ресурса помечается как устаревшая.
POST
Применяется для передачи пользовательских данных заданному ресурсу. Например, в блогах посетители обычно могут вводить свои комментарии к записям в HTML-форму, после чего они передаются серверу методом POST и он помещает их на страницу. При этом передаваемые данные (в примере с блогами - текст комментария) включаются в тело запроса. Аналогично с помощью метода POST обычно загружаются файлы на сервер.
В отличие от метода GET , метод POST не считается идемпотентным , то есть многократное повторение одних и тех же запросов POST может возвращать разные результаты (например, после каждой отправки комментария будет появляться одна копия этого комментария).
При результате выполнения 200 (Ok) в тело ответа следует включить сообщение об итоге выполнения запроса. Если был создан ресурс, то серверу следует вернуть ответ 201 (Created) с указанием URI нового ресурса в заголовке Location .
Сообщение ответа сервера на выполнение метода POST не кэшируется.
PUT
Применяется для загрузки содержимого запроса на указанный в запросе URI. Если по заданному URI не существовало ресурса, то сервер создаёт его и возвращает статус 201 (Created). Если же был изменён ресурс, то сервер возвращает 200 (Ok) или 204 (No Content). Сервер не должен игнорировать некорректные заголовки Content-* передаваемые клиентом вместе с сообщением. Если какой-то из этих заголовков не может быть распознан или не допустим при текущих условиях, то необходимо вернуть код ошибки 501 (Not Implemented).
Фундаментальное различие методов POST и PUT заключается в понимании предназначений URI ресурсов. Метод POST предполагает, что по указанному URI будет производиться обработка передаваемого клиентом содержимого. Используя PUT , клиент предполагает, что загружаемое содержимое соответствует находящемуся по данному URI ресурсу.
Сообщения ответов сервера на метод PUT не кэшируются.
PATCH
Аналогично PUT, но применяется только к фрагменту ресурса.
DELETE
Удаляет указанный ресурс.
TRACE
Возвращает полученный запрос так, что клиент может увидеть, какую информацию промежуточные серверы добавляют или изменяют в запросе.
LINK
Устанавливает связь указанного ресурса с другими.
UNLINK
Убирает связь указанного ресурса с другими.
CONNECT
Преобразует соединение запроса в прозрачный TCP/IP туннель, обычно чтобы содействовать установлению защищенного SSL соединения через нешифрованный прокси.
Коды состояния
Код состояния является частью первой строки ответа сервера. Он представляет собой целое число из трех арабских цифр . Первая цифра указывает на класс состояния. За кодом ответа обычно следует отделённая пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа. Примеры:
201 Webpage Created 403 Access allowed only for registered users 507 Insufficient Storage
Клиент узнаёт по коду ответа о результатах его запроса и определяет, какие действия ему предпринимать дальше. Набор кодов состояния является стандартом, и они описаны в соответствующих документах RFC . Введение новых кодов должно производиться только после согласования с IETF . Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода.
В настоящее время выделено пять классов кодов состояния.
1xx Informational (рус. Информационный )В этот класс выделены коды, информирующие о процессе передачи. В HTTP/1.0 сообщения с такими кодами должны игнорироваться. В HTTP/1.1 клиент должен быть готов принять этот класс сообщений как обычный ответ, но ничего отправлять серверу не нужно. Сами сообщения от сервера содержат только стартовую строку ответа и, если требуется, несколько специфичных для ответа полей заголовка. Прокси-серверы подобные сообщения должны отправлять дальше от сервера к клиенту.
2xx Success (рус. Успех )Сообщения данного класса информируют о случаях успешного принятия и обработки запроса клиента. В зависимости от статуса сервер может ещё передать заголовки и тело сообщения.
3xx Redirection (рус. Перенаправление )Коды класса 3xx сообщают клиенту что для успешного выполнения операции необходимо сделать другой запрос (как правило по другому URI). Из данного класса пять кодов , , , и относятся непосредственно к перенаправлениям (редирект). Адрес, по которому клиенту следует произвести запрос, сервер указывает в заголовке Location . При этом допускается использование фрагментов в целевом URI.
4xx Client Error (рус. Ошибка клиента )Класс кодов 4xx предназначен для указания ошибок со стороны клиента. При использовании всех методов, кроме HEAD , сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя.
Для запоминания значений кодов с 400 по 417 существуют приёмы иллюстративной мнемотехники
5xx Server Error (рус. Ошибка сервера )Коды 5xx выделены под случаи неудачного выполнения операции по вине сервера. Для всех ситуаций, кроме использования метода HEAD , сервер должен включать в тело сообщения объяснение, которое клиент отобразит пользователю.
Заголовки
Тело сообщения
Тело HTTP сообщения (message-body), если оно присутствует, используется для передачи тела объекта, связанного с запросом или ответом. Тело сообщения (message-body) отличается от тела объекта (entity-body) только в том случае, когда применяется кодирование передачи, что указывается полем заголовка Transfer-Encoding.
Message-body = entity-body
|
Поле Transfer-Encoding должно использоваться для указания любого кодирования передачи, примененного приложением в целях гарантирования безопасной и правильной передачи сообщения. Поле Transfer-Encoding - это свойство сообщения, а не объекта, и, таким образом, может быть добавлено или удалено любым приложением в цепочке запросов/ответов.
Правила, устанавливающие допустимость тела сообщения в сообщении, отличны для запросов и ответов.
Присутствие тела сообщения в запросе отмечается добавлением к заголовкам запроса поля заголовка Content-Length или Transfer-Encoding. Тело сообщения (message-body) МОЖЕТ быть добавлено в запрос только когда метод запроса допускает тело объекта (entity-body).
Включается или не включается тело сообщения (message-body) в сообщение ответа зависит как от метода запроса, так и от кода состояния ответа. Все ответы на запрос с методом HEAD не должны включать тело сообщения (message-body), даже если присутствуют поля заголовка объекта (entity-header), заставляющие поверить в присутствие объекта. Никакие ответы с кодами состояния 1xx (Информационные), 204 (Нет содержимого, No Content), и 304 (Не модифицирован, Not Modified) не должны содержать тела сообщения (message-body). Все другие ответы содержат тело сообщения, даже если оно имеет нулевую длину.
Примеры диалогов HTTP
Обычный GET-запрос
Различают два основных типа согласований:
- Управляемое сервером (англ. Server-Driven ).
- Управляемое клиентом (англ. Agent-Driven ).
Одновременно могут быть использованы оба типа или каждый из них по отдельности.
В основной спецификации по протоколу (RFC 2616) также выделяется так называемое прозрачное согласование (англ. Transparent Negotiation ) как предпочтительный вариант комбинирования обоих типов. Последний механизм не следует путать с независимой технологией Transparent Content Negotiation (TCN, рус. Прозрачное согласование содержимого , см. RFC 2295), которая не является частью протокола HTTP, но может использоваться с ним. У обоих существенное различие в принципе работы и самом значении слова «прозрачное» (transparent). В спецификации по HTTP под прозрачностью подразумевается, что процесс не заметен для клиента и сервера, а в технологии TCN прозрачность означает доступность полного списка вариантов ресурса для всех участников процесса доставки данных.
Управляемое сервером
При наличии нескольких версий ресурса сервер может анализировать заголовки запроса клиента, чтобы выдать, по его мнению, наиболее подходящую. В основном анализируются заголовки Accept , Accept-Charset , Accept-Encoding , Accept-Languages и User-Agent . Серверу желательно включать в ответ заголовок Vary с указанием параметров, по которым различается содержимое по запрашиваемому URI.
Географическое положение клиента можно определить по удалённому IP-адресу . Это возможно за счёт того что IP-адреса, как и доменные имена , регистрируются на конкретного человека или организацию. При регистрации указывается регион, в котором будет использоваться желаемое адресное пространство. Эти данные общедоступны, и в Интернете можно найти соответствующие свободно распространяемые базы данных и готовые программные модули для работы с ними (следует ориентироваться на ключевые слова «Geo IP»).
Следует помнить что такой метод способен определить местоположение максимум с точностью до города (отсюда определяется и страна). При этом информация актуальна только на момент регистрации адресного пространства. Например, если московский провайдер зарегистрирует диапазон адресов с указанием Москвы и начнёт предоставлять доступ клиентам из ближайшего Подмосковья, то его абоненты могут на некоторых сайтах наблюдать, что они из Москвы, а не из Красногорска или Дзержинского .
Управляемое сервером согласование имеет несколько недостатков:
- Сервер только предполагает, какой вариант наиболее предпочтителен для конечного пользователя, но не может знать точно, что именно нужно в данный момент (например, версия на русском языке или английском).
- Заголовков группы Accept передаётся много, а ресурсов с несколькими вариантами - мало. Из-за этого оборудование испытывает избыточную нагрузку.
- Общему кэшу создаётся ограничение возможности выдавать один и тот же ответ на идентичные запросы от разных пользователей.
- Передача заголовков Accept также может раскрывать некоторые сведения о его предпочтениях, таких как используемые языки, браузер, кодировка.
Управляемое клиентом
В данном случае тип содержимого определяется только на стороне клиента. Для этого сервер возвращает с кодом состояния 300 (Multiple Choices) или 406 (Not Acceptable) список вариантов, среди которых пользователь выбирает подходящий. Управляемое клиентом согласование хорошо, когда содержимое различается по самым частым параметрам (например, по языку и кодировке) и используется публичный кэш.
Основной недостаток - лишняя нагрузка, так как приходится делать дополнительный запрос, чтобы получить нужное содержимое.
Прозрачное согласование
Данное согласование полностью прозрачно для клиента и сервера. В данном случае используется общий кэш, в котором содержится список вариантов, как для управляемого клиентом согласования. Если кэш понимает все эти варианты, то он сам делает выбор, как при управляемом сервером согласовании. Это снижает нагрузки с исходного сервера и исключает дополнительный запрос со стороны клиента.
В основной спецификации по протоколу HTTP механизм прозрачного согласования подробно не описан.
Множественное содержимое
Протокол HTTP поддерживает передачу нескольких сущностей в пределах одного сообщения. Причём сущности могут передаваться не только в виде одноуровневой последовательности, но в виде иерархии с вложением элементов друг в друга. Для обозначения множественного содержимого используются медиатипы multipart/* . Работа с такими типами осуществляется по общим правилам, описанным в RFC 2046 (если иное не определено конкретным медиа типом). Если получателю не известно как работать с типом, то он обрабатывает его так же, как multipart/mixed .
Параметр boundary означает разделитель между различными типами передаваемых сообщений. Например передаваемый из формы параметр DestAddress передает значение e-mail адреса, а последущий за ним элемент AttachedFile1 отправляет двоичное содержимое изображения формата.jpg
Со стороны сервера сообщения со множественным содержимым могут посылаться в ответ на при запросе нескольких фрагментов ресурса. В этом случае используется медиа тип multipart/byteranges .
Со стороны клиента при отправке HTML -формы чаще всего пользуются методом POST . Типичный пример: страницы отправки электронных писем со вложенными файлами. При отправке такого письма браузер формирует сообщение типа multipart/form-data , интегрируя в него как отдельные части, введённые пользователем, тему письма, адрес получателя, сам текст и вложенные файлы:
POST /send-message.html HTTP/1.1 Host: mail.example.com Referer: http://mail.example.com/send-message.html User-Agent: BrowserForDummies/4.67b Content-Type: multipart/form-data; boundary="Asrf456BGe4h" Content-Length: (суммарный объём, включая дочерние заголовки) Connection: keep-alive Keep-Alive: 300 (пустая строка) (отсутствующая преамбула) --Asrf456BGe4h Content-Disposition: form-data; name="DestAddress" (пустая строка) [email protected] --Asrf456BGe4h Content-Disposition: form-data; name="MessageTitle" (пустая строка) Я негодую --Asrf456BGe4h Content-Disposition: form-data; name="MessageText" (пустая строка) Привет, Василий! Твой ручной лев, которого ты оставил у меня на прошлой неделе, разодрал весь мой диван. Пожалуйста, забери его скорее! Во вложении две фотки с последствиями. --Asrf456BGe4h Content-Disposition: form-data; name="AttachedFile1"; filename="horror-photo-1.jpg" Content-Type: image/jpeg (пустая строка) (двоичное содержимое первой фотографии) --Asrf456BGe4h Content-Disposition: form-data; name="AttachedFile2"; filename="horror-photo-2.jpg" Content-Type: image/jpeg (пустая строка) (двоичное содержимое второй фотографии) --Asrf456BGe4h-- (отсутствующий эпилог)
В примере в заголовках Content-Disposition параметр name соответствует атрибуту name в HTML-тегах и
Особенности протокола
Большинство протоколов предусматривают установление TCP-сессии, в ходе которой один раз происходит авторизация, и дальнейшие действия выполняются в контексте этой авторизации. HTTP же устанавливает отдельную TCP-сессию на каждый запрос; в более поздних версиях HTTP было разрешено делать несколько запросов в ходе одной TCP-сессии, но браузеры обычно запрашивают только страницу и включённые в неё объекты (картинки, каскадные стили и т. п.), а затем сразу разрывают TCP-сессию. Для поддержки авторизованного (неанонимного) доступа в HTTP используются cookies ; причём такой способ авторизации позволяет сохранить сессию даже после перезагрузки клиента и сервера.
При доступе к данным по FTP или по файловым протоколам тип файла (точнее, тип содержащихся в нём данных) определяется по расширению имени файла, что не всегда удобно. HTTP перед тем, как передать сами данные, передаёт заголовок «Content-Type: тип/подтип», позволяющую клиенту однозначно определить, каким образом обрабатывать присланные данные. Это особенно важно при работе с CGI-скриптами, когда расширение имени файла указывает не на тип присылаемых клиенту данных, а на необходимость запуска данного файла на сервере и отправки клиенту результатов работы программы, записанной в этом файле (при этом один и тот же файл в зависимости от аргументов запроса и своих собственных соображений может порождать ответы разных типов - в простейшем случае картинки в разных форматах).
Кроме того, HTTP позволяет клиенту прислать на сервер параметры, которые будут переданы запускаемому CGI-скрипту. Для этого же в HTML были введены формы.
Перечисленные особенности HTTP позволили создавать поисковые машины (первой из которых стала AltaVista, созданная фирмой DEC), форумы и Internet-магазины. Это коммерциализировало Интернет, появились компании, основным полем деятельности которых стало предоставление доступа в Интернет (провайдеры) и создание сайтов.
Примечания
См. также
Ссылки
Позволяющий получать различные ресурсы, например HTML-документы. Протокол HTTP лежит в основе обмена данными в Интернете. HTTP является протоколом клиент-серверного взаимодействия, что означает инициирование запросов к серверу самим получателем, обычно веб-браузером. Полученный итоговый документ будет реконструирован из различных субдокументов, например, из отдельно полученного текста, описания структуры документа, изображений, видео-файлов, скриптов и многого другого.
Клиенты и серверы взаимодействуют, обмениваясь индивидуальными сообщениями (а не потоком данных). Сообщения, отправленные клиентом, обычно веб-браузером, называются запросами , а сообщения, отправленные сервером, называются ответами .
Хотя HTTP был разработан еще в начале 1990-х годов, за счет своей расширяемости в дальнейшем он все время совершенствовался. HTTP является протоколом прикладного уровня, который чаще всего использует возможности другого протокола - TCP (или TLS - защищённый TCP) - для пересылки своих сообщений, однако любой другой надежный транспортный протокол теоретически может быть использован для доставки таких сообщений. Благодаря своей расширяемости, он используется не только для получения клиентом гипертекстовых документов либо изображений и видео, но и для передачи контента серверам, например, с помощью HTML-форм. HTTP также может быть использован для получения только частей документа с целью обновления веб-страницы по запросу.
Компоненты систем, основанных на HTTP
HTTP - это клиент-серверный протокол, то есть запросы отправляются какой-то одной стороной - юзер-агентом (user-agent) (либо прокси вместо него). Чаще всего в качестве юзер-агента выступает веб-браузер, но им может быть кто угодно, например, робот, путешествующий по Сети для пополнения и обновления данных индексации веб-страниц для поисковых систем.
Каждый индивидуальный запрос (англ. request ) отправляется серверу, который обрабатывает его и возвращает ответ (англ. response ). Между этими запросами и ответами существуют многочисленные посредники, называемые прокси , которые выполняют различные операции и работают как шлюзы или кэш , например.
В реальности, между браузером и сервером гораздо больше различных устройств-посредников, которые играют какую-либо роль в обработке запроса: роутеры, модемы и так далее. Благодаря тому, что Сеть построена на основе системы уровней (слоёв) взаимодействия, эти посредники "спрятаны" на сетевом и транспортном уровнях. В этой системе уровней HTTP занимает самый верхний уровень, который называется "прикладным" (или "уровнем приложений"). Знания об уровнях сети, таких как представительский, сеансовый, транспортный, сетевой, канальный и физический, имея важное значение для понимания работы сети и диагностики возможных проблем, не требуются для описания и понимания HTTP.
Клиент: юзер-агент
Юзер-агент - это любой инструмент или устройство, действующие от лица пользователя. Эта роль преимущественно принадлежит веб-браузеру; в некоторых случаях юзер-агентами выступают программы, которые используются инженерами и веб-разработчиками для отладки своих приложений.
Браузер всегда является той сущностью, которая инициирует запрос. Сервер никогда этого не делает (хотя за многие годы существования сети были созданы механизмы, которые могут симулировать запросы со стороны сервера).
Чтобы отобразить веб страницу, браузер отправляет начальный запрос для получения HTML-документа этой страницы. После этого браузер анализирует этот документ, и запрашивает дополнительные файлы, необходимые для отбражения содержания веб-страницы (исполняемые скрипты, информацию о макете страницы - CSS таблицы стилей, дополнительные ресурсы в виде изображений и видео-файлов). Далее браузер соединяет все эти ресурсы для отображения их пользователю в виде единого документа - веб-страницы. Скрипты, выполняемые самим браузером, могут получать по сети дополнительные ресурсы на последующих этапах обработки веб-страницы, и браузер соотвествующим образом обновляет представление этой страницы для пользователя.
Веб-страница является гипертекстовый документом. Это означает, что некоторые части отображаемого текста являются ссылками, которые могут быть активированы (обычно нажатием кнопки мыши) с целью получения и соответственно отображения новой веб-страницы. Это позволяет пользователю направлять своего юзер-агента, осуществляя навигацию по Сети. Браузер транслирует эти "направления движения" в HTTP-запросы и в дальнейшем интерпретирует HTTP-ответы в понятном для пользователя виде.
Веб-сервер
На другой стороне коммуникационного канала расположен сервер, который обслуживает (англ. serve ) пользователя, предоставляя ему документы по запросу. С точки зрения конечного пользователя, сервер всегда является некой одной виртуальной машиной, полностью или частично генерирующей документ, хотя фактически он может быть группой серверов, между которыми балансируется нагрузка, то есть перераспределяются запросы различных пользователей, либо сложным программным обеспечением, опрашивающим другие компьютеры (такие как кэширующие серверы, серверы баз данных, серверы приложений электронной коммерции и другие).
Сервер не обязательно расположен на одной машине, и наоборот - несколько серверов могут быть расположены (хоститься) на одной и той же машине. В соответствии с версией HTTP/1.1 и имея Host заголовок, они даже могут делить тот же самый IP-адрес.
Прокси
Между веб-браузером и сервером находятся большое количество сетевых узлов передающих HTTP сообщения. Из за слоистой структуры, большинство из них оперируют также на транспортном сетевом или физическом уровнях, становясь прозрачным на HTTP слое и потенциально снижая производительность. Эти операции на уровне приложений называются прокси . Они могут быть прозрачными, или нет, (изменяющие запросы не пройдут через них), и способны исполнять множество функций:
- caching (кеш может быть публичным или приватными, как кеш браузера)
- фильтрация (как сканирование антивируса, родительский контроль, …)
- выравнивание нагрузки (позволить нескольким серверам обслуживать разные запросы)
- аутотентификация (контролировать доступом к разным ресурсам)
- протоколирование (разрешение на хранение истории операций)
Основные аспекты HTTP
HTTP - прост
Даже с большей сложностью, введенной в HTTP/2 путем инкапсуляции HTTP-сообщений в фреймы, HTTP, как правило, прост и удобен для восприятия человеком. HTTP-сообщения могут читаться и пониматься людьми, обеспечивая более легкое тестирование разработчиков и уменьшенную сложность для новых пользователей.
HTTP - расширяемый
Введенные в HTTP/1.0 HTTP-заголовки сделали этот протокол легким для расширения и экспериментирования. Новая функциональность может быть даже введена простым соглашением между клиентом и сервером о семантике нового заголовка.
HTTP не имеет состояния, но имеет сессию
HTTP не имеет состояния: не существует связи между двумя запросами, которые последовательно выполняются по одному соединению. Из этого немедленно следует возможность проблем для пользователя, пытающегося взаимодействовать с определенной страницей последовательно, например, при использовании корзины в электронном магазине. Но хотя ядро HTTP не имеет состояния, куки позволяют использовать сессии с сохранением состояния. Используя расширяемость заголовков, куки добавляются к рабочему потоку, позволяя сессии на каждом HTTP-запросе делиться некоторым контекстом, или состоянием.
HTTP и соединения
Содинение управляется на транспортном уровне, и потому принципиально выходит за границы HTTP. Хотя HTTP не требует, чтобы базовый транспортного протокол был основан на соединениях, требуя только надёжность , или отсутствие потерянных сообщений (т.е. как минимум представление ошибки). Среди двух наиболее распространенных транспортных протоколов Интернета, TCP надёжен, а UDP -- нет. HTTP впоследствии полагается на стандарт TCP, являющийся основанным на соединениях, несмотря на то, что соединение не всегда требуется.
HTTP/1.0 открывал TCP-соединение для каждого обмена запросом/ответом, имея два важных недостатка: открытие соединения требует нескольких обменов сообщениями, и потому медленно, хотя становится более эффективным при отправке нескольких сообщений, или при регулярной отправке сообщений: теплые соединения более эффективны, чем холодные .
Для смягчения этих недостатков, HTTP/1.1 предоставил конвеерную обработку (которую оказалось трудно реализовать) и устойчивые соединения: лежащее в основе TCP соединение можно частично контролировать через заголовок Connection . HTTP/2 сделал следующий шаг, добавив мультиплексирование сообщений через простое соединение, помогающее держать соединение теплым и более эффективным.
Проводятся эксперименты по разработке лучшего транспортного протокола, более подходящего для HTTP. Например, Google эксперементирует с QUIC , которая основана на UDP, для предоставления более надёжного и эффективного транспортного протокола.
Чем можно управлять через HTTP
Естественная расширяемость HTTP со временем позволила большее управление и функциональность Сети. Кэш и методы аутентификации были ранними функциями в истории HTTP. Способность ослабить первоначальные ограничения, напротив, была добавлена в 2010-е.
Ниже перечислены общие функции, управляемые с HTTP.
-
Сервер может инструктировать прокси и клиенты: что и как долго кэшировать. Клиент может инструктировать прокси промежуточных кэшей игнорировать хранимые документы. - Ослабление ограничений источника
Для предотвращения шпионских и других, нарушающих приватность, вторжений, веб-браузер обчеспечивает строгое разделеление между веб-сайтами. Только страницы из того же источника могут получить доступ к информации на веб-странице. Хотя такие ограничение нагружают сервер, заголовки HTTP могут ослабить строгое разделение на стороне сервера, позволяя документу стать частью информации с различных доменов (по причинам безопасности). - Аутентификация
Некоторые страницы доступны только специальным пользователям. Базовая аутентификация может предоставляться через HTTP, либо через использование заголовка WWW-Authenticate и подобных ему, либо с помощью настройки спецсессии, используя куки. - Прокси и тунелирование
Серверы и/или клиенты часто располагаются в интранете, и скрывают свои истинные IP-адреса от других. HTTP запросы идут через прокси для пересечения этого сетевого барьера. Не все прокси -- HTTP прокси. SOCKS-протокол, например, оперирует на более низком уровне. Другие, как, например, ftp, могут быть обработаны этими прокси. - Сессии
Использование HTTP кук позволяет связать запрос с состоянием на сервере. Это создает сессию, хотя ядро HTTP -- протокол без состояния. Это полезно не только для корзин в интернет-магазинах, но также для любых сайтов, позволяющих пользователю настроить выход.
HTTP поток
Когда клиент хочет взаимодействовать с сервером, являясь конечным сервером или промежуточным прокси, он выполняет следующие шаги:
- Открытие TCP соединения: TCP-соедиенение будет использоваться для отправки запроса или запросов, и получения ответа. Клиент может открыть новое соединение, переиспользовать существующее, или открыть несколько TCP-соединений к серверу.
- Отправка HTTP-сообщения: HTTP-собщения (до HTTP/2) -- человеко-читаемо. Начиная с HTTP/2, простые сообщения инкапсилуруются во фреймы, делая невозможным их чтения напрямую, но принципиально остаются такими же. GET / HTTP/1.1 Host: сайт Accept-Language: fr
- Читает ответ от сервера: HTTP/1.1 200 OK Date: Sat, 09 Oct 2010 14:28:02 GMT Server: Apache Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT ETag: "51142bc1-7449-479b075b2891b" Accept-Ranges: bytes Content-Length: 29769 Content-Type: text/html
- Закрывает или переиспользует соединение для дальнейщих запросов.
Если активирован HTTP-конвеер, несколько запросов могут быть отправлены без ожидания получения первого ответа целиком. HTTP-конвеер тяжело внедряется в существующие сети, где старые куски ПО сосуществуют с современными версиями. HTTP-конвеер был заменен в HTTP/2 на более надежные мультиплексивные запросы во фрейме.
HTTP сообщения
HTTP/1.1 и более ранние HTTP сообщения человеко-читаемы. В версии HTTP/2 эти сообщения встроены в новую бинарную структуру, фрейм, позволяющий оптимизации, такие как компрессия заголовков и мультиплексирование. Даже если часть оригинального HTTP сообщения отправлена в этой версии HTTP, семантика каждого сообщения не изменяется и клиент воссоздаёт (виртуально) оригинальный HTTP-запрос. Это также полезно для понимания HTTP/2 сообщений в формате HTTP/1.1.
HTTP (HyperText Transfer Protocol - протокол передачи гипертекста) был разработан как основа World Wide Web.
Работа по протоколу HTTP происходит следующим образом: программа-клиент устанавливает TCP-соединение с сервером (стандартный номер порта-80) и выдает ему HTTP-запрос. Сервер обрабатывает этот запрос и выдает HTTP-ответ клиенту.
Структура HTTP-запроса
HTTP-запрос состоит из заголовка запроса и тела запроса, разделенных пустой строкой. Тело запроса может отсутствовать.
Заголовок запроса состоит из главной (первой) строки запроса и последующих строк, уточняющих запрос в главной строке. Последующие строки также могут отсутствовать.
Запрос в главной строке состоит из трех частей, разделенных пробелами:
Метод (иначе говоря, команда HTTP):
GET - запрос документа. Наиболее часто употребляемый метод; в HTTP/0.9, говорят, он был единственным.
HEAD - запрос заголовка документа. Отличается от GET тем, что выдается только заголовок запроса с информацией о документе. Сам документ не выдается.
POST - этот метод применяется для передачи данных CGI-скриптам. Сами данные следуют в последующих строках запроса в виде параметров.
PUT - разместить документ на сервере. Насколько я знаю, используется редко. Запрос с этим методом имеет тело, в котором передается сам документ.
Ресурс - это путь к определенному файлу на сервере, который клиент хочет получить (или разместить - для метода PUT). Если ресурс - просто какой-либо файл для считывания, сервер должен по этому запросу выдать его в теле ответа. Если же это путь к какому-либо CGI-скрипту, то сервер запускает скрипт и возвращает результат его выполнения. Кстати, благодаря такой унификации ресурсов для клиента практически безразлично, что он представляет собой на сервере.
Версия протокола -версия протокола HTTP, с которой работает клиентская программа.
Таким образом, простейший HTTP-запрос может выглядеть следующим образом:
Здесь запрашивается корневой файл из корневой директории web-сервера.
Строки после главной строки запроса имеют следующий формат:
Параметр: значениe .
Таким образом задаются параметры запроса. Это является необязательным, все строки после главной строки запроса могут отсутствовать; в этом случае сервер принимает их значение по умолчанию или по результатам предыдущего запроса (при работе в режиме Keep-Alive).
Перечислю некоторые наиболее употребительные параметры HTTP-запроса:
Connection
(соединение)- может принимать значения Keep-Alive и close.
Keep-Alive ("оставить в живых") означает, что после выдачи данного документа
соединение с сервером не разрывается, и можно выдавать еще запросы.
Большинство браузеров работают именно в режиме Keep-Alive, так как он
позволяет за одно соединение с сервером "скачать" html-страницу и рисунки
к ней. Будучи однажды установленным, режим Keep-Alive сохраняется до
первой ошибки или до явного указания в очередном запросе Connection: close.
close ("закрыть") - соединение закрывается после ответа на данный запрос.
User-Agent - значением является "кодовое обозначение" браузера, например:
Mozilla/4.0 (compatible; MSIE 5.0; Windows 95; DigExt)
Accept - список поддерживаемых браузером типов содержимого в порядке их предпочтения данным браузером, например для моего IE5:
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*
Это, очевидно, нужно для случая, когда сервер может выдавать один и тот же документ в разных форматах.
Значение этого параметра используется в основном CGI-скриптами для формирования ответа, адаптированного для данного браузера.
Referer - URL, с которого перешли на этот ресурс.
Host - имя хоста, с которого запрашивается ресурс. Полезно, если на сервере имеется несколько виртуальных серверов под одним IP-адресом. В этом случае имя виртуального сервера определяется по этому полю.
Accept-Language - поддерживаемый язык. Имеет значение для сервера, который может выдавать один и тот же документ в разных языковых версиях.
Формат HTTP-ответа
Формат ответа очень похож на формат запроса: он также имеет заголовок и тело, разделенное пустой строкой.
Заголовок также состоит из основной строки и строк параметров, но формат основной строки отличается от таковой в заголовке запроса.
Основная строка запроса состоит из 3-х полей, разделенных пробелами:
Версия протокола - аналогичен соответствующему параметру запроса.
Код ошибки - кодовое обозначение "успешности" выполнения запроса. Код 200 означает "все нормально" (OK).
Словесное описание ошибки - "расшифровка" предыдущего кода. Например для 200 это OK, для 500 - Internal Server Error.
Наиболее употребительные параметры http-ответа:
Connection
- аналогичен соответствующему параметру запроса.
Если сервер не поддерживает Keep-Alive (есть и такие), то значение
Connection в ответе всегда close.
Поэтому, на мой взгляд, правильной тактикой браузера является следующая:
1. выдать в запросе Connection: Keep-Alive;
2. о состоянии соединения судить по полю Connection в ответе.
Content-Type ("тип содержимого") - содержит обозначение типа содержимого ответа.
В зависимости от значения Content-Type браузер воспринимает ответ как HTML-страницу, картинку gif или jpeg, как файл, который надо сохранить на диске, или как что-либо еще и предпринимает соответствующие действия. Значение Content-Type для браузера аналогично значению расширения файла для Windows.
Некоторые типы содержимого:
text/html - текст в формате HTML (веб-страница);
text/plain - простой текст (аналогичен "блокнотовскому");
image/jpeg - картинка в формате JPEG;
image/gif - то же, в формате GIF;
application/octet-stream - поток "октетов" (т.е. просто байт) для записи
на диск.
На самом деле типов содержимого гораздо больше.
Content-Length ("длина содержимого") - длина содержимого ответа в байтах.
Last-Modified ("Модифицирован в последний раз") - дата последнего изменения документа.
Протокол HTTP (HyperText Transfer Protocol - протокол передачи гипертекста) - это протокол уровня приложения, осуществляющий связь приложений в пределах распределенных, совместных или разнородных информационных систем. Протокол позволяет приложениям обмениваться данными, представленными в понятном для восприятия человеком виде.
Как следует из его названия, первоначально HTTP предназначался для передачи между приложениями так называемого гипертекста (hypertext), представляющего собой особый вид данных, созданный в соответствии со стандартом HTML (HyperText Markup Language - язык разметки гипертекста). Гипертекстовый документ состоит из данных, размеченных с помощью тегов (tag) языка HTML, и представляет собой комбинацию текста, изображений, гиперссылок и прочих средств представления данных. Гиперссылки - одна из важнейших составляющих HTML-документа - представляют собой интерактивные области, воздействие на которые приводит к получению связанных с гиперссылкой данных. Это позволяет пользователю, работающему с гипертекстовой информацией, осуществлять навигацию в пределах набора документов или даже всей сети Интернет, получая интересующую его информацию с помощью контекстных гиперссылок.
Протокол HTTP является надстройкой над протоколом TCP и является средством контроля содержания передаваемых данных. В отличие от TCP, который не учитывал структуру передаваемых пакетов, HTTP внедряет в данные метаинформацию, позволяющую получателю корректно интерпретировать полученные данные. На основе HTTP функционирует глобальная сеть Интернет (называемая также World Wide Web или WWW). Первая версия протокола - HTTP/0.9 - обладала достаточно ограниченными возможностями, но с активным развитием всемирной сети появились новые версии: HTTP/1.0 и HTTP/1.1, позволяющие контролировать передачу по вычислительным сетям не только гипертекстовой информации, но и произвольные бинарные файлы: звуковые, графические, архивные и пр.
В силу того, что HTTP является надстройкой над протоколом TCP, при передачи данных также выделяются две стороны: клиент и сервер.
Клиент является инициатором соединения и запрашивает у сервера некоторые данные или услуги. Клиентом, как правило, является программа, называемая браузером (browser), позволяющая как отображать гипертекстовую информацию, так и принимать файлы иных форматов. Чтобы получить некоторую интересующую информацию, клиент посылает серверу запрос (request), содержащий описание запрашиваемой информации.
Сервер при передаче данных через HTTP называют веб-сервером (web-server). Эта программа осуществляет обработку запросов от клиентов, передавая запрошенные данные в виде ответов (response), содержащих помимо искомых данных метаинформацию, их описывающую.
Получение пользователем интересующих его данных состоит из следующих этапов:
Пользователь вводит в строке браузера адрес интересующего его ресурса.
Браузер на основе информации, полученной от пользователя, а также учитывая свои настройки и конфигурацию операционной системы, формирует запрос.
Браузер подключается к серверу, расположенном, возможно, на удаленном компьютере, и передает ему запрос.
Сервер, анализируя запрос, выполняет необходимые действия: формирует ответ, включая в него тело запрошенного документа. Если это гипертекстовый документ, он загружается из файла или же генерируется динамически посредством сценария. В ответ также включается информация о содержащихся в нем данных.
Сервер передает ответ браузеру.
Браузер анализирует ответ и либо сохраняет полученные данные в файл, либо, в случае гипертекстового документа, анализирует теги HTML и отображает документ на экране.
Следует заметить, что клиентской программой может быть не только браузер, тем не менее, все шаги, за исключением, может быть, первого, выполняются в любом случае.
Следует заметить, что здесь рассматривается непосредственное подключение клиента к серверу, содержащему интересующую информацию, однако, это не всегда возможно в силу различных обстоятельств. В таком случае подключение может осуществляться посредством одной или более промежуточных точек подключения. Можно разделить эти промежуточные точки на три группы:
Прокси-серверы (proxy-server) - программа-посредник, выполняющая функции как клиента, так и сервера с целью создания запросов от имени других клиентов. Запросы обслуживаются прокси-сервером, или пересылаются им с внесением в них изменений (в этом случае прокси-сервер называется непрозрачным) или без изменений (в этом случае прокси-сервер называется прозрачным). Прокси-сервер позволяет группе компьютеров выступать в качестве одного клиента, что часто применяется при подключении к Интернету локальных сетей.
Шлюз (gateway) - как и прокси-сервер, осуществляет трансляцию запросов, однако, не подвергаю их изменению. Шлюз получает от клиента запрос, как к серверу, содержащему искомый ресурс. Таким образом, клиент не может определить, подключается ли он через шлюз или непосредственно к содержащему ресурс серверу.
Туннель (tunnel) - программа-посредник, поддерживающая соединение. Хотя после установки соединения туннель не рассматривается в качестве элемента передачи через протокол HTTP, соединение, как правило, инициируется именно HTTP-запросом. Туннель прерывает свою работу, если хотя бы один из участников обмена данными закрывает соединение.
Для сохранения функциональности передачи данных при подключении через промежуточные точки не требуется внесения изменений в запросы и ответы, за исключением случая прокси-сервера: в этом случае в клиентском запросе должны содержаться дополнительные поля. Однако, с точки зрения сервера, обмен данными производится непосредственно с клиентом, следовательно, никаких изменений в запросах не происходит. Поэтом при разработке программы возможность подключения через промежуточные точки не учитывалась.
Запрос, отправляемый клиентом серверу, служит для точной идентификации запрашиваемого ресурса, а также содержит сведения, необходимые для корректной обработки запроса.
По своей структуре запрос состоит из трех частей:
Строка запроса
Блок заголовков
Строка запроса состоит из трех полей, разделенных символами пробела (ASCII-код 20h, далее SP), и заканчивается комбинацией из двух символов: возврат каретки (ASCII-код 0Dh, далее CR) и перевод строки (ASCII-код 0Ah, далее LF). Элементы строки запроса представлены следующими полями:
Метод (method) - определяет метод обработки, применяемый к запрашиваемому ресурсу. В зависимости от указанного метода формат запроса может быть различным. Допустимые методы:
При разработке программы была введена поддержка только метода GET, в силу того, что именно этот метод браузер указывает в запросе, создаваемом по умолчанию.
URI (Universal Resource Identifier) ресурса (resource URI) - указывает местоположение запрашиваемого ресурса в стандартизованном формате, то есть является адресом ресурса. При использовании метода GET данная строка может включать в себя набор параметров, передаваемых серверу в виде строк формата «имя_параметра = значение_параметра», разделенных символами амперсанда `&". Блок параметров находится в конце строки URI и отделяется от адреса символом вопросительного знака `?".
Версия протокола HTTP - при разработке программы была реализована поддержка приема запросов, соответствующих версиям 1.0 и 1.1, которым соответствуют строки «HTTP/1.0» и «HTTP/1.1» соответственно.
Блок заголовков, следующий за строкой запроса, может состоять из одного или более заголовков:
Заголовок запроса - содержит поля, служащие модификаторами запроса и содержащие информацию о запросе и о конфигурации клиентской машины.
Заголовок объекта - в случае, если запрос включает в себя некоторый объект (произвольный набор данных), поля этого заголовка описывают объект, указывая его формат, кодировку и другие параметры.
Общий заголовок - содержит служебные параметры, необходимые для обеспечения корректности передачи и включения дополнительных услуг, таких, как кэширование.
Раздел заголовков оканчивается двумя парами символов CR и LF, что позволяет легко определить факт окончания приема запроса в силу того, что сам запрос подобную комбинацию символов содержать не может.
Ответ, отправляемый сервером клиенту, может быть создан только в результате обработки клиентского запроса. Он содержит описание результатов выполнения запроса и, если были запрошены данные, включает в себя запрошенный ресурс.
По своей структуре ответ состоит из следующих частей:
Строка состояния
Блок заголовков
Строка состояния состоит из трех полей, разделенных символами SP, и содержит в конце последовательность символов CR, LF. Элементы строки состояния:
Версия протокола HTTP - разработанная программа всегда использует строку «HTTP/1.1».
Код состояния (status code) - трехсимвольный цифровой код, который идентифицирует результат выполнения запроса. Хотя стандартом определен достаточно большой набор кодов состояния, в программе используются следующие коды:
- 200 - успешное выполнение;
- 400 - некорректный запрос;
- 401 - несанкционированный доступ;
- 404 - ресурс не найден;
- 405 - неприменимый метод;
- 505 - неподдерживаемая версия HTTP.
Фраза состояния (reason phrase) - короткая фраза, поясняющая код состояния выполнения запроса. Стандартом предложен стандартный набор фраз, однако в программе этот набор был несколько модифицирован.
Блок заголовков, следующий за строкой состояния, может состоять из одного или более заголовков:
Заголовок запроса
Заголовок объекта
Общий заголовок
Подробное рассмотрение заголовков было произведено в п. 2.2.3.3.
Раздел заголовков оканчивается двумя парами символов CR и LF, после чего следует произвольный набор символов - объект. При работе программы такими объектами могут являться только гипертекстовые документы в формате HTML, динамически генерируемые подключаемыми модулями.
Вашему вниманию предлагается описание основных аспектов протокола HTTP - сетевого протокола, с начала 90-х и по сей день позволяющего вашему браузеру загружать веб-страницы. Данная статья написана для тех, кто только начинает работать с компьютерными сетями и заниматься разработкой сетевых приложений, и кому пока что сложно самостоятельно читать официальные спецификации.
HTTP - широко распространённый протокол передачи данных, изначально предназначенный для передачи гипертекстовых документов (то есть документов, которые могут содержать ссылки, позволяющие организовать переход к другим документам).
Аббревиатура HTTP расшифровывается как HyperText Transfer Protocol , «протокол передачи гипертекста». В соответствии со спецификацией OSI , HTTP является протоколом прикладного (верхнего, 7-го) уровня. Актуальная на данный момент версия протокола, HTTP 1.1, описана в спецификации RFC 2616 .
Протокол HTTP предполагает использование клиент-серверной структуры передачи данных. Клиентское приложение формирует запрос и отправляет его на сервер, после чего серверное программное обеспечение обрабатывает данный запрос, формирует ответ и передаёт его обратно клиенту. После этого клиентское приложение может продолжить отправлять другие запросы, которые будут обработаны аналогичным образом.
Задача, которая традиционно решается с помощью протокола HTTP - обмен данными между пользовательским приложением, осуществляющим доступ к веб-ресурсам (обычно это веб-браузер) и веб-сервером. На данный момент именно благодаря протоколу HTTP обеспечивается работа Всемирной паутины.
Также HTTP часто используется как протокол передачи информации для других протоколов прикладного уровня, таких как SOAP, XML-RPC и WebDAV. В таком случае говорят, что протокол HTTP используется как «транспорт».
API многих программных продуктов также подразумевает использование HTTP для передачи данных - сами данные при этом могут иметь любой формат, например, XML или JSON.
Как правило, передача данных по протоколу HTTP осуществляется через TCP/IP-соединения. Серверное программное обеспечение при этом обычно использует TCP-порт 80 (и, если порт не указан явно, то обычно клиентское программное обеспечение по умолчанию использует именно 80-й порт для открываемых HTTP-соединений), хотя может использовать и любой другой.
Как отправить HTTP-запрос?
Самый простой способ разобраться с протоколом HTTP - это попробовать обратиться к какому-нибудь веб-ресурсу вручную. Представьте, что вы браузер, и у вас есть пользователь, который очень хочет прочитать статьи Анатолия Ализара.Предположим, что он ввёл в адресной строке следующее:
Http://alizar.сайт/
Соответственно вам, как веб-браузеру, теперь необходимо подключиться к веб-серверу по адресу alizar.сайт.
Для этого вы можете воспользоваться любой подходящей утилитой командной строки. Например, telnet:
Telnet alizar.сайт 80
Сразу уточню, что если вы вдруг передумаете, то нажмите Ctrl + «]», и затем ввод - это позволит вам закрыть HTTP-соединение. Помимо telnet можете попробовать nc (или ncat) - по вкусу.
После того, как вы подключитесь к серверу, нужно отправить HTTP-запрос. Это, кстати, очень легко - HTTP-запросы могут состоять всего из двух строчек.
Для того, чтобы сформировать HTTP-запрос, необходимо составить стартовую строку, а также задать по крайней мере один заголовок - это заголовок Host, который является обязательным, и должен присутствовать в каждом запросе. Дело в том, что преобразование доменного имени в IP-адрес осуществляется на стороне клиента, и, соответственно, когда вы открываете TCP-соединение, то удалённый сервер не обладает никакой информацией о том, какой именно адрес использовался для соединения: это мог быть, например, адрес alizar..ru или m.. Однако фактически сетевое соединение во всех случаях открывается с узлом 212.24.43.44, и даже если первоначально при открытии соединения был задан не этот IP-адрес, а какое-либо доменное имя, то сервер об этом никак не информируется - и именно поэтому этот адрес необходимо передать в заголовке Host.
Стартовая (начальная) строка запроса для HTTP 1.1 составляется по следующей схеме:
Например (такая стартовая строка может указывать на то, что запрашивается главная страница сайта):
Ну и, конечно, не забывайте, что любая технология становится намного проще и понятнее тогда, когда вы фактически начинаете ей пользоваться.
Удачи и плодотворного обучения!
Теги:
- http
- alizar
- spdy