Что такое http в информатике
Обзор протокола HTTP
HTTP — это протокол, позволяющий получать различные ресурсы, например HTML-документы. Протокол HTTP лежит в основе обмена данными в Интернете. HTTP является протоколом клиент-серверного взаимодействия, что означает инициирование запросов к серверу самим получателем, обычно веб-браузером (web-browser). Полученный итоговый документ будет (может) состоять из различных поддокументов, являющихся частью итогового документа: например, из отдельно полученного текста, описания структуры документа, изображений, видео-файлов, скриптов и многого другого.
Клиенты и серверы взаимодействуют, обмениваясь одиночными сообщениями (а не потоком данных). Сообщения, отправленные клиентом, обычно веб-браузером, называются запросами, а сообщения, отправленные сервером, называются ответами.
Составляющие систем, основанных на HTTP
HTTP — это клиент-серверный протокол, то есть запросы отправляются какой-то одной стороной — участником обмена (user-agent) (либо прокси вместо него). Чаще всего в качестве участника выступает веб-браузер, но им может быть кто угодно, например, робот, путешествующий по Сети для пополнения и обновления данных индексации веб-страниц для поисковых систем.
Каждый запрос (англ. request) отправляется серверу, который обрабатывает его и возвращает ответ (англ. response). Между этими запросами и ответами как правило существуют многочисленные посредники, называемые прокси, которые выполняют различные операции и работают как шлюзы или кэш, например.
Обычно между браузером и сервером гораздо больше различных устройств-посредников, которые играют какую-либо роль в обработке запроса: маршрутизаторы, модемы и так далее. Благодаря тому, что Сеть построена на основе системы уровней (слоёв) взаимодействия, эти посредники «спрятаны» на сетевом и транспортном уровнях. В этой системе уровней HTTP занимает самый верхний уровень, который называется «прикладным» (или «уровнем приложений»). Знания об уровнях сети, таких как представительский, сеансовый, транспортный, сетевой, канальный и физический, имеют важное значение для понимания работы сети и диагностики возможных проблем, но не требуются для описания и понимания HTTP.
Клиент: участник обмена
Участник обмена (user agent) — это любой инструмент или устройство, действующие от лица пользователя. Эту задачу преимущественно выполняет веб-браузер; в некоторых случаях участниками выступают программы, которые используются инженерами и веб-разработчиками для отладки своих приложений.
Браузер всегда является той сущностью, которая создаёт запрос. Сервер обычно этого не делает, хотя за многие годы существования сети были придуманы способы, которые могут позволить выполнить запросы со стороны сервера.
Веб-страница является гипертекстовым документом. Это означает, что некоторые части отображаемого текста являются ссылками, которые могут быть активированы (обычно нажатием кнопки мыши) с целью получения и соответственно отображения новой веб-страницы (переход по ссылке). Это позволяет пользователю «перемещаться» по страницам сети (Internet). Браузер преобразует эти гиперссылки в HTTP-запросы и в дальнейшем полученные HTTP-ответы отображает в понятном для пользователя виде.
Веб-сервер
На другой стороне коммуникационного канала расположен сервер, который обслуживает (англ. serve) пользователя, предоставляя ему документы по запросу. С точки зрения конечного пользователя, сервер всегда является некой одной виртуальной машиной, полностью или частично генерирующей документ, хотя фактически он может быть группой серверов, между которыми балансируется нагрузка, то есть перераспределяются запросы различных пользователей, либо сложным программным обеспечением, опрашивающим другие компьютеры (такие как кеширующие серверы, серверы баз данных, серверы приложений электронной коммерции и другие).
Прокси
Между веб-браузером и сервером находятся большое количество сетевых узлов, передающих HTTP сообщения. Из-за слоистой структуры большинство из них оперируют также на транспортном сетевом или физическом уровнях, становясь прозрачным на HTTP слое и потенциально снижая производительность. Эти операции на уровне приложений называются прокси. Они могут быть прозрачными или нет, (изменяющие запросы не пройдут через них), и способны исполнять множество функций:
Основные аспекты HTTP
Даже с большей сложностью, введённой в HTTP/2 путём инкапсуляции HTTP-сообщений в фреймы, HTTP, как правило, прост и удобен для восприятия человеком. HTTP-сообщения могут читаться и пониматься людьми, обеспечивая более лёгкое тестирование разработчиков и уменьшенную сложность для новых пользователей.
Введённые в HTTP/1.0 HTTP-заголовки сделали этот протокол лёгким для расширения и экспериментирования. Новая функциональность может быть даже введена простым соглашением между клиентом и сервером о семантике нового заголовка.
HTTP не имеет состояния, но имеет сессию
HTTP не имеет состояния: не существует связи между двумя запросами, которые последовательно выполняются по одному соединению. Из этого немедленно следует возможность проблем для пользователя, пытающегося взаимодействовать с определённой страницей последовательно, например, при использовании корзины в электронном магазине. Но хотя ядро HTTP не имеет состояния, куки позволяют использовать сессии с сохранением состояния. Используя расширяемость заголовков, куки добавляются к рабочему потоку, позволяя сессии на каждом HTTP-запросе делиться некоторым контекстом или состоянием.
HTTP и соединения
Соединение управляется на транспортном уровне, и потому принципиально выходит за границы HTTP. Хотя HTTP не требует, чтобы базовый транспортного протокол был основан на соединениях, требуя только надёжность, или отсутствие потерянных сообщений (т.е. как минимум представление ошибки). Среди двух наиболее распространённых транспортных протоколов Интернета, TCP надёжен, а UDP — нет. HTTP впоследствии полагается на стандарт TCP, являющийся основанным на соединениях, несмотря на то, что соединение не всегда требуется.
HTTP/1.0 открывал TCP-соединение для каждого обмена запросом/ответом, имея два важных недостатка: открытие соединения требует нескольких обменов сообщениями, и потому медленно, хотя становится более эффективным при отправке нескольких сообщений, или при регулярной отправке сообщений: тёплые соединения более эффективны, чем холодные.
Проводятся эксперименты по разработке лучшего транспортного протокола, более подходящего для HTTP. Например, Google экспериментирует с QUIC (которая основана на UDP) для предоставления более надёжного и эффективного транспортного протокола.
Чем можно управлять через HTTP
Естественная расширяемость HTTP со временем позволила большее управление и функциональность Сети. Кеш и методы аутентификации были ранними функциями в истории HTTP. Способность ослабить первоначальные ограничения, напротив, была добавлена в 2010-е.
Ниже перечислены общие функции, управляемые с HTTP.
HTTP поток
Когда клиент хочет взаимодействовать с сервером, являющимся конечным сервером или промежуточным прокси, он выполняет следующие шаги:
Если активирован HTTP-конвейер, несколько запросов могут быть отправлены без ожидания получения первого ответа целиком. HTTP-конвейер тяжело внедряется в существующие сети, где старые куски ПО сосуществуют с современными версиями. HTTP-конвейер был заменён в HTTP/2 на более надёжные мультиплексные запросы во фрейме.
HTTP сообщения
HTTP/1.1 и более ранние HTTP сообщения человекочитаемые. В версии HTTP/2 эти сообщения встроены в новую бинарную структуру, фрейм, позволяющий оптимизации, такие как компрессия заголовков и мультиплексирование. Даже если часть оригинального HTTP сообщения отправлена в этой версии HTTP, семантика каждого сообщения не изменяется и клиент воссоздаёт (виртуально) оригинальный HTTP-запрос. Это также полезно для понимания HTTP/2 сообщений в формате HTTP/1.1.
Существует два типа HTTP сообщений, запросы и ответы, каждый в своём формате.
Запросы
Примеры HTTP запросов:
Запросы содержат следующие элементы:
Ответы
Ответы содержат следующие элементы:
Вывод
HTTP — лёгкий в использовании расширяемый протокол. Структура клиент-сервера, вместе со способностью к простому добавлению заголовков, позволяет HTTP продвигаться вместе с расширяющимися возможностями Сети.
Хотя HTTP/2 добавляет некоторую сложность, встраивая HTTP сообщения во фреймы для улучшения производительности, базовая структура сообщений осталась с HTTP/1.0. Сессионный поток остаётся простым, позволяя исследовать и отлаживать с простым монитором HTTP-сообщений.
HTTP: Протокол, который должен знать каждый веб-разработчик (Часть 1)
Давайте рассмотрим этот мощный протокол через призму веб-разработчика. Мы разберем эту тему в двух частях руководства. В первой мы рассмотрим основы и дадим общее представление о заголовках запроса и ответа. В последующей части мы рассмотрим специальные вопросы технологии HTTP, а именно: кэширование, реализацию соединения и аутентификацию (* в системе компьютерной безопасности – процесс, позволяющий установить, что пользователь или компьютер (сервер), пытающийся получить интерактивный доступ к определенной категории информации, компьютерной системе, вычислительной сети или электронной почте, действительно тот, за кого себя выдает).
Хотя я упомяну некоторые детали насчет заголовков, за исчерпывающим описанием вам лучше будет обратиться к RFC (RFC 2616). Я буду ссылаться на определенные части документа RFC на протяжении статьи.
Основы HTTP
HTTP позволяет общаться системам с различной архитектурой и конфигурацией сети (* включает в себя конкретный состав оборудования ЛВС, схему его соединения и сетевое ПО).
Это возможно благодаря тому, что этот протокол предъявляет самые общие требования к системам и не сохраняет состояние между обменами различными сообщениями.
По этой причине HTTP считается протоколом без запоминания состояния. Для транспортировки сообщений обычно служит протокол TCP (* Transmission Control Protocol; протокол управления передачей, протокол TCP широко используемый в Internet протокол транспортного уровня из набора TCP/IP. Гарантирует доставку передаваемых пакетов данных в нужной последовательности, но трафик при этом может быть весьма неравномерен, так как пакеты испытывают всевозможные задержки), однако может использоваться любой другой подходящий механизм для транспортировки сообщений (* например, QUIC (Quick UDP Internet Connections) – экспериментальный интернет-протокол, разработанный Google в конце 2012 года). Портом по умолчанию для HTTP является порт 80, но могут использоваться и другие порты.
Также можно добавлять и отправлять специализированные (* связанные с (конкретным) применением, в отличие от стандартизованных в RFC заголовков) собственные заголовки к серверу (* и от сервера).
Обмен сообщениями между клиентом и сервером идет по схеме «запрос-ответ». Клиент начинает общение, отправляя сообщение запроса HTTP, в ответ на которое сервер отсылает сообщение ответа HTTP. Мы рассмотрим эту основополагающую пару в следующем разделе.
Текущая версия протокола – HTTP/1.1, в которой добавлены дополнительные возможности по сравнению с предыдущей – HTTP/1.0. Среди них, на мой взгляд, наиболее важными являются: долговременные соединения (* persistent connections; передача в одном TCP-соединении нескольких объектов, причем время существования соединения определяется при конфигурировании веб-службы), кодирование передачи данных типа «chunked» (* по частям) (* chunked transfer-coding; механизм передачи данных в протоколе передачи гипертекста (HTTP), позволяющий надежно доставлять данные от сервера клиенту (чаще всего клиентскому web-браузеру) без необходимости заранее знать точный размер всего тела HTTP-сообщения. Это достигается разбиением сообщения на небольшие части (chunks), а затем передачей каждой части с указанием только её размера (в шестнадцатеричном виде). Окончание передачи сообщения определяется наличием последней части с нулевой длиной. Такой механизм позволяет передать динамически сформированные объекты, для которых нельзя заранее определить размер. Он стал доступен только начиная с HTTP версии 1.1 (HTTP/1.1). Без механизма сhunked transfer encoding с каждым HTTP-пакетом необходимо указывать заголовок Content-Length, чтобы клиент мог найти конец передаваемого сообщения) и тонко гранулированные (* метафорическое определение (обозначение) процесса или системы для работы с небольшими объектами, например, отдельными битами и байтами, а не с относительно большими объектами, например файлами или записями) заголовки, при помощи которых задаются директивы для механизма кэширования. Мы коротко рассмотрим эти возможности в этой части; детальное рассмотрение будет во второй.
URL-адреса
Методы
Также в их распоряжении имеются прокси для отладки веб-приложений, например, Fiddler (* работает с трафиком между вашим компьютером и удаленным сервером и позволяет просматривать и менять его) (для Windows) и Charles Proxy (для OSX).
URL-ссылки идентифицируют определенный сервер, с которым мы хотим наладить обмен сообщениями, однако действие, которое должно быть выполнено на сервере, указывается при помощи методов HTTP. Естественно, что клиент хотел бы выполнить некоторые действия (* методы) на сервере. В HTTP стандартизированы несколько, благодаря которым можно реализовать самые необходимые возможности; эти методы универсальны для всех видов приложений.
Эти методы запроса перечислены ниже:
Выше перечисленные методы наиболее распространены, и большинство инструментов и фреймворков предоставляют функции для работы с этими методами. Иногда PUT и DELETE рассматриваются как специализированные версии метода POST и могут быть оформлены в виде запросов по методу POST с данными, определяющими точное действие: создать, обновить, удалить.
Также HTTP поддерживает некоторые реже используемые методы:
Коды состояния (* значение, возвращаемой процедурой или функцией, показывающее состояние устройства или процесса)
Имея URL-адреса и методы, клиент может инициировать запросы к серверу. В ответ сервер присылает ответы с кодами состояния и содержимым сообщений. Код состояния – важный компонент сообщения; он указывает клиенту, как интерпретировать ответ сервера. В спецификации (* документ, который в идеале содержит полное, точное, детальное описание функций и/или параметров (например, продукта, программы, стандарта и т. п.), а также, возможно, процедур, позволяющих определить, соответствует ли продукт данной спецификации) HTTP устанавливаются определенные диапазоны чисел для конкретных типов ответов:
1xx: Информация о процессе передачи
Всем клиентам HTTP/1.1 необходимо, чтобы в сообщении был заголовок Transfer-Encoding.
Этот класс кодов появился в HTTP/1.1 и используется просто для предварительного общения клиента и сервера. Сервер может отослать в ответ на сообщение клиента с заголовком Expect: 100-continue ответ (* например, 100 Continue (Продолжать) (код и соответствующая поясняющая фраза)), инструктируя клиента продолжить отправление оставшейся части запроса или проигнорировать сообщение, если тот уже ее отослал. При работе через HTTP/1.0 сообщения с такими кодами должны игнорироваться (* в версии 1.1 клиент должен быть готов принять этот класс сообщений как обычный ответ, но серверу отправлять что-либо не нужно).
2xx: Информация об успешном принятии и обработке запроса клиента
Коды этого класса сообщают клиенту, что его запрос успешно обработан. Наиболее часто встречается код (* и соответствующая поясняющая фраза) 200 OK. На запросы по методу GET сервер отсылает в ответ запрашиваемые данные в теле сообщения. Ниже перечислены некоторые более редко используемые коды (* и соответствующие фразы):
3xx: Перенаправление
404 сообщает, что запрашиваемый ресурс не существует на сервере.
Этот код указывает клиенту, что необходимо будет выполнить дополнительное действие. Самый распространенный вариант – выполнение запроса по другому URL-адресу (* указанному в дополнительном заголовке Location) для получения запрашиваемого ресурса.
4xx: Информация об ошибках со стороны клиента
5xx: Информация об ошибках со стороны сервера
Этот тип кодов используется для сообщения о неуспешном выполнении операции по вине сервера. Наиболее часто встречающийся код об ошибке (* и соответствующая поясняющая фраза) – 500 Internal Server Error (* Внутренняя ошибка сервера; любая внутренняя ошибка сервера, которая не входит в рамки остальных ошибок класса). Некоторые остальные коды (* и соответствующие поясняющие фразы) этого класса включают:
Формат HTTP-сообщений
На данный момент мы выяснили, что URL-адреса, методы и коды состояния – это фундаментальные компоненты пары HTTP запрос/ответ.
Теперь давайте рассмотрим содержимое этих сообщений. В спецификации HTTP определяется следующая общая структура сообщений запроса и ответа:
Размещение пустой строки между заголовками и телом сообщения является обязательным. В сообщении может содержаться один или несколько заголовков, среди которых условно (* согласно контексту) можно выделить:
В теле сообщения могут содержаться все данные сообщения или оно может быть разбито на части, если используется кодирование передачи типа «chunked» (Transfer-Encoding: chunked). Всем клиентам HTTP/1.1 необходимо, чтобы в сообщении был заголовок Transfer-Encoding.
Общие заголовки
Имеется несколько заголовков (общие заголовки), которые используются и в сообщениях запроса, и в сообщениях ответа:
Мы уже знакомы с некоторыми из этих заголовков ( Via и Transfer-Encoding ). Мы рассмотрим Cache-Control и Connection во второй части.
Код состояния – важный компонент сообщения; он указывает клиенту, как интерпретировать ответ сервера.
Заголовки для тела сообщения
В сообщениях запроса и ответа также могут использоваться заголовки для тела объекта, чтобы передать мета-информацию о содержимом сообщения (тело сообщения/объекта). Этот тип заголовков включает:
При помощи всех заголовков с префиксом Content- передается информация о структуре, кодировании и размере тела сообщения. Некоторые из этих заголовков должны присутствовать, если в сообщении имеется содержимое.
Благодаря заголовку Expires указывается срок, по истечении которого тело сообщения считается устаревшим. Интересно то, что при указании значения «never expires» этот срок равен одному году. При помощи заголовка Last-Modified указывается время последней модификации файла.
Также можно добавлять и отправлять специализированные собственные заголовки к серверу (* и от сервера); согласно протоколу HTTP они будут рассматриваться как заголовки объекта.
Эта возможность – механизм расширения полей заголовка (* позволяет вводить дополнительные поля заголовка объекта (entity-header fields), не изменяя протокол, но эти поля могут быть и не распознаны получателем. Получатель должен игнорировать нераспознанные поля заголовка, а прокси-сервер должен просто пересылать их без изменений), и в некоторых реализациях приложений для коммуникации могут использоваться именно эти специальные заголовки. Хотя HTTP поддерживает специализированные заголовки, в первую очередь его интересуют заголовки ответа и запроса, которые мы и будем рассматривать далее.
Формат сообщений запроса
Общая структура сообщения запроса такая же, как и выше, однако строка запроса выглядит следующим образом:
SP – пространственный разделитель между лексемами. На месте HTTP-Version указывается «HTTP/1.1«, и затем идет переход на новую строку. Таким образом, типичное сообщение запроса может выглядеть следующим образом:
Обратите внимание на строку запроса, за которой идет серия заголовков запроса. Заголовок Host является обязательным для клиентов, работающих по HTTP/1.1. Запросы, выполняемые по методу GET, не имеют тела объекта, а запросы, выполняемые по методу POST, могут содержать данные в теле для создания ресурса.
Заголовки запроса играют роль модификаторов сообщения запроса. Полный список имеющихся заголовков запроса не слишком длинный и приведен ниже. Не входящие в перечень заголовки рассматриваются как поля заголовка объекта.
Формат сообщений ответа
Формат сообщений ответа сходен с таковым сообщений запроса, за исключением стартовой строки и заголовков. Стартовая строка имеет следующую структуру:
Типичная стартовая строка ответа об успешном выполнении запроса может выглядеть следующим образом:
Число заголовков ответа также довольно ограничено; полный набор представлен ниже:
Мы ознакомились с большим объемом теории на данный момент, так что не удивительно, если вы немного задремали. В следующих разделах у нас будет больше практики и мы поработаем с некоторыми инструментами, фреймворками и библиотеками.
Инструменты для просмотра сетевого трафика по HTTP (* поток данных в передающей среде; состоит из передаваемых данных и служебной информации, необходимой для организации их прохождения)
Разработчикам доступно множество инструментов для мониторинга HTTP трафика. Здесь будут перечислены наиболее популярные.
Без сомнений, фаворитом среди веб-разработчиков является инспектор Chrome/Webkit.
Также в их распоряжении имеются прокси для отладки веб-приложений, например, Fiddler (* работает с трафиком между вашим компьютером и удаленным сервером и позволяет просматривать и менять его) для Windows и Charles Proxy для OSX. Мой коллега, Rey Bango, написал замечательную статью на эту тему. Мой коллега, Rey Bango, написал замечательную статью на эту тему.
Из набора программ с интерфейсом командной строки для мониторинга трафика HTTP у нас имеются такие утилиты, как curl, tcpdump и tshark.
Использование HTTP во фреймворках и библиотеках
Теперь, когда мы рассмотрели сообщения запроса/ответа, пришло время ознакомиться с тем, какой API библиотеки и фремворки предоставляют для работы с ними. Мы рассмотрим примеры из ExpressJS (для Node), Ruby on Rails (* фреймворк, написанный на языке программирования Ruby, реализует архитектурный шаблон Model-View-Controller для веб-приложений, а также обеспечивает их интеграцию с веб-сервером и сервером баз данных) и jQuery Ajax. Мы рассмотрим примеры из ExpressJS (для Node), Ruby on Rails (* фреймворк, написанный на языке программирования Ruby, реализует архитектурный шаблон Model-View-Controller для веб-приложений, а также обеспечивает их интеграцию с веб-сервером и сервером баз данных) и jQuery Ajax.
ExpressJS
Если вы создаете веб-серверы на Node.js, то наверняка уже знакомы с ExpressJS. Прототипом ExpressJS послужил веб-фреймворк для Ruby – Sinatra. Не удивительно, что API ExpressJS подобен его API.
Поскольку мы имеем дело с фреймворком для серверной стороны, то при работе с сообщениями HTTP необходимо выполнить два действия:
ExpressJS как раз предоставляет для этого простой API. Мы не будем рассматривать детали API. Вместо этого я предоставлю вам ссылки на детальную документацию по ExpressJS. Здесь будут перечислены наиболее популярные. Некоторые примеры методов API, связанных с обработкой запросов, приведены ниже:
Для формирования ответа клиенту ExpressJS предоставляет следующий API:
Ruby on Rails
Формат сообщений запроса и ответа сходен (различия есть в стартовой строке и заголовках сообщений).
В Rails модули ActionController и ActionDispatch предоставляют API для обработки сообщений запроса и ответа.
Для работы с ответом модуль предоставляет методы cookies(), location=() и status=(). Если вы хотите поэкспериментировать, то можете также задать тело ответа вручную при помощи body=().
AJAX (* Asynchronous JavaScript And XML – асинхронный JavaScript + XML) jQuery
Поскольку jQuery – прежде всего, библиотека для клиентской части приложения, то API AJAX предоставляет возможности, противоположные тем, что реализуются на стороне сервера. Другими словами, благодаря ей вы можете прочитывать и изменять сообщения запроса. jQuery предоставляет доступ к простому API при помощи jQuery.ajax(settings):
Резюме
Давайте теперь подведем итог нашему краткому разбору протокола HTTP.
Мы ознакомились со структурой URL-адреса, методами и кодами состояния – тремя китами коммуникации при помощи HTTP.
Формат сообщений запроса и ответа сходен (различия есть в стартовой строке и заголовках сообщений). И, наконец, мы рассмотрели, как вы можете работать с заголовками запроса и ответа во фреймворках и библиотеках.
Понимание HTTP очень важно для реализации простого добротного RESTful (* веб-службы, построенные с учётом REST (передача состояния представления; архитектурный стиль взаимодействия компонентов распределенного приложения в сети)) интерфейса между двумя оконечными узлами локальной сети (* ЛС). По большому счету (* исходя из самых строгих требований) эти знания вам также пригодятся при создании вашей сетевой инфраструктуры (* совокупность аппаратных и программных средств, предоставляющая пользователю необходимые сетевые возможности) и обеспечении для конечных пользователей удобства использования.
Во второй части мы разберем реализацию соединений, аутентификацию и кэширование! Тогда и увидимся.