Протокол HTTP
Основным объектом манипуляции в HTTP является ресурс, на который указывает URI (Uniform Resource Identifier – уникальный идентификатор ресурса) в запросе клиента. Основными ресурсами являются хранящиеся на сервере файлы, но ими могут быть и другие логические (напр. каталог на сервере) или абстрактные объекты (напр. ISBN). Протокол HTTP позволяет указать способ представления (кодирования) одного и того же ресурса по различным параметрам: mime-типу, языку и т. д. Благодаря этой возможности клиент и веб-сервер могут обмениваться двоичными данными, хотя данный протокол является текстовым.
Структура HTTP-запросов и ответов
В HTTP и запрос, и ответ имеют похожую структуру:
- URL
- Метод
- Версия HTTP
- Заголовки
- Статус-код (обязательно только для HTTP-ответов)
- Тело (необязательно)
Пример HTTP-запроса:
POST /cgi-bin/process.cgi HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
licenseID=string&content=string&/paramsXML=string
POST
метод/cgi-bin/process.cgi
URLHTTP/1.1
версия протокола HTTPUser-Agent
,Host
и другие заголовкиlicenseID=string&content=string&/paramsXML=string
тело запроса
Пример HTTP-ответа, где отсутствует URL и метод, зато появился статус-код 200
, означающий «успех»:
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
Content-Length: 88
Content-Type: text/html
Connection: Closed
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Методы HTTP-запросов
Если при повторении одного и того же запроса на сервере ничего не меняется, запрос считается идемпотентным. Если повторение одинакового запроса несколько раз изменяет состояние сервера, то он не идемпотентен и, вообще говоря, менее безопасен.
Метод HTTP — последовательность из любых символов, кроме управляющих и разделителей, указывающая на основную операцию над ресурсом. Обычно метод представляет собой короткое английское слово, записанное заглавными буквами:
Метод
|
Краткое описание
|
---|---|
OPTIONS
|
Используется для определения возможностей веб-сервера или параметров соединения для конкретного ресурса. Предполагается, что запрос клиента может содержать тело сообщения для указания интересующих его сведений. Формат тела и порядок работы с ним в настоящий момент не определён. Сервер пока должен его игнорировать. Аналогичная ситуация и с телом в ответе сервера. Для того чтобы узнать возможности всего сервера, клиент должен указать в URI звёздочку — «*». Запросы «OPTIONS * HTTP/1.1» могут также применяться для проверки работоспособности сервера (аналогично «пингованию») и тестирования на предмет поддержки сервером протокола HTTP версии 1.1. Результат выполнения этого метода не кэшируется. |
GET
|
Используется для запроса содержимого указанного ресурса. С помощью метода GET можно также начать какой-либо процесс. В этом случае в тело ответного сообщения следует включить информацию о ходе выполнения процесса. Клиент может передавать параметры выполнения запроса в URI целевого ресурса после символа «?»: GET /path/resource?param1=value1¶m2=value2 HTTP/1.1. Согласно стандарту HTTP, запросы типа GET считаются идемпотентными — многократное повторение одного и того же запроса GET должно приводить к одинаковым результатам (при условии, что сам ресурс не изменился за время между запросами). Это позволяет кэшировать ответы на запросы GET. Кроме обычного метода GET, различают ещё условный GET и частичный GET. Условные запросы GET содержат заголовки If-Modified-Since, If-Match, If-Range и подобные. Частичные GET содержат в запросе Range. Порядок выполнения подобных запросов определён стандартами отдельно. |
HEAD
|
Аналогичен методу GET, за исключением того, что в ответе сервера отсутствует тело. Запрос HEAD обычно применяется для извлечения метаданных, проверки наличия ресурса (валидация URL) и чтобы узнать, не изменился ли он с момента последнего обращения. Заголовки ответа могут кэшироваться. При несовпадении метаданных ресурса с соответствующей информацией в кэше копия ресурса помечается как устаревшая. |
POST
|
Применяется для передачи пользовательских данных заданному ресурсу. Например, в блогах посетители обычно могут вводить свои комментарии к записям в HTML-форму, после чего они передаются серверу методом POST и он помещает их на страницу. При этом передаваемые данные (в примере с блогами — текст комментария) включаются в тело запроса. Аналогично с помощью метода POST обычно загружаются файлы. В отличие от метода GET, метод POST не считается идемпотентным, то есть многократное повторение одних и тех же запросов POST может возвращать разные результаты (например, после каждой отправки комментария будет появляться одна копия этого комментария). При результатах выполнения 200 (Ok) и 204 (No Content) в тело ответа следует включить сообщение об итоге выполнения запроса. Если был создан ресурс, то серверу следует вернуть ответ 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
|
Убирает связь указанного ресурса с другими. |
Каждый сервер обязан поддерживать как минимум методы GET и HEAD. Если сервер не распознал указанный клиентом метод, то он должен вернуть статус 501 (Not Implemented). Если серверу метод известен, но он не применим к конкретному ресурсу, то возвращается сообщение с кодом 405 (Method Not Allowed). В обоих случаях серверу следует включить в сообщение ответа заголовок Allow со списком поддерживаемых методов. Наиболее востребованными являются методы GET и POST — на человеко-ориентированных ресурсах, POST — роботами поисковых машин и оффлайн-браузерами.
Прокси-сервер это транзитный сервер, перенаправляющий HTTP-трафик. Прокси-серверы используются для ускорения выполнения запросов путем кэширования веб-страниц. В локальной сети применяется как межсетевой экран и средство управления HTTP-трафиком (например, для блокирования доступа к некоторым ресурсам). В Интернете прокси часто используют для анонимизации запросов - в этом случае веб-сервер получает ip-адрес прокси-сервера, а не реального клиента. В современных браузерах можно задать целый список прокси и переключаться между серверами из этого списка по мере необходимости (обычно такая возможность доступна через расширения или плагины браузера).
Статус-коды ответа
Каждый код представляется целым трехзначным числом. Первая цифра указывает на класс состояния, последующие - порядковый номер состояния. За кодом ответа обычно следует краткое описание на английском языке.
Класс кодов
|
Краткое описание
|
---|---|
1xx Informational (Информационный)
|
В этот класс выделены коды, информирующие о процессе передачи. В HTTP/1.0 сообщения с такими кодами должны игнорироваться. В HTTP/1.1 клиент должен быть готов принять этот класс сообщений как обычный ответ, но ничего отправлять серверу не нужно. Сами сообщения от сервера содержат только стартовую строку ответа и, если требуется, несколько специфичных для ответа полей заголовка. Прокси-сервера подобные сообщения должны отправлять дальше от сервера к клиенту. Примеры ответов сервера:
|
2xx Success (Успешно)
|
Сообщения данного класса информируют о случаях успешного принятия и обработки запроса клиента. В зависимости от статуса сервер может ещё передать заголовки и тело сообщения. Примеры ответов сервера: 200 OK (Успешно).
|
3xx Redirection (Перенаправление)
|
Коды статуса класса 3xx сообщают клиенту, что для успешного выполнения операции нужно произвести следующий запрос к другому URI. В большинстве случаев новый адрес указывается в поле Location заголовка. Клиент в этом случае должен, как правило, произвести автоматический переход (жарг. «редирект»). Обратите внимание, что при обращении к следующему ресурсу можно получить ответ из этого же класса кодов. Может получиться даже длинная цепочка из перенаправлений, которые, если будут производиться автоматически, создадут чрезмерную нагрузку на оборудование. Поэтому разработчики протокола HTTP настоятельно рекомендуют после второго подряд подобного ответа обязательно запрашивать подтверждение на перенаправление у пользователя (раньше рекомендовалось после 5-го). За этим следить обязан клиент, так как текущий сервер может перенаправить клиента на ресурс другого сервера. Клиент также должен предотвратить попадание в круговые перенаправления. Примеры ответов сервера:
|
4xx Client Error (Ошибка клиента)
|
Класс кодов 4xx предназначен для указания ошибок со стороны клиента. При использовании всех методов, кроме HEAD, сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя. Примеры ответов сервера:
|
5xx Server Error (Ошибка сервера)
|
Коды 5xx выделены под случаи неудачного выполнения операции по вине сервера. Для всех ситуаций, кроме использования метода HEAD, сервер должен включать в тело сообщения объяснение, которое клиент отобразит пользователю. Примеры ответов сервера:
|
Заголовки HTTP
Заголовки — часть HTTP-запроса и/или HTTP-ответа, они не видимы пользователю. Представляют собой пары ключ: значение
.
Все HTTP-заголовки разделяются на четыре основных группы:
General
Headers (основные заголовки) должны включаться в любое сообщение клиента и сервераRequest
Headers (заголовки запроса) используются только в запросах клиентаResponse
Headers (заголовки ответа) присутствуют только в ответах сервераEntity
Headers (заголовки сущности) сопровождают каждую сущность сообщения
Сущности (entity
, в переводах также встречается название "объект") — это полезная информация, передаваемая в запросе или ответе. Сущность состоит из метаинформации (заголовки) и непосредственно содержания (тело сообщения).
В отдельный класс заголовки сущности выделены, чтобы не путать их с заголовками запроса или заголовками ответа при передаче множественного содержимого multipart
. Заголовки запроса и ответа, как и основные заголовки, описывают всё сообщение в целом и размещаются только в начальном блоке заголовков, в то время как заголовки сущности характеризуют содержимое каждой части в отдельности, располагаясь непосредственно перед её телом.
Заголовок
|
Группа
|
Краткое описание
|
---|---|---|
Allow
|
Entity
|
Список методов, применимых к запрашиваемому ресурсу |
Content-Encoding
|
Entity
|
Применяется при необходимости перекодировки содержимого например, gzip/deflated
|
Content-Language
|
Entity
|
Локализация содержимого язык(и) |
Content-Length
|
Entity
|
Размер тела сообщения в октетах |
Content-Range
|
Entity
|
Диапазон используется для поддержания многопоточной загрузки или дозагрузки |
Content-Type
|
Entity
|
Указывает тип содержимого mime-type , например text/html .Часто включает указание на таблицу символов локали charset
|
Expires
|
Entity
|
Дата/время, после которой ресурс считается устаревшим. Используется прокси-серверами |
Last-Modified
|
Entity
|
Дата/время последней модификации сущности |
Cache-Control
|
General
|
Определяет директивы управления механизмами кэширования. Для прокси-серверов |
Connection
|
General
|
Задает параметры, требуемые для конкретного соединения |
Date
|
General
|
Дата и время формирования сообщения |
Pragma
|
General
|
Используется для специальных указаний, которые могут (опционально) применяется к любому получателю по всей цепочке запросов/ответов например, pragma: no-cache
|
Transfer-Encoding
|
General
|
Задает тип преобразования, применимого к телу сообщения. В отличие от Content-Encoding этот заголовок распространяется на все сообщение, а не только на сущность
|
Via
|
General
|
Используется шлюзами и прокси для отображения промежуточных протоколов и узлов между клиентом и веб-сервером |
Warning
|
General
|
Дополнительная информация о текущем статусе, которая не может быть представлена в сообщении |
Accept
|
Request
|
Определяет применимые типы данных, ожидаемых в ответе |
Accept-Charset
|
Request
|
Определяет кодировку символов charset для данных, ожидаемых в ответе
|
Accept-Encoding
|
Request
|
Определяет применимые форматы кодирования/декодирования содержимого например, gzip
|
Accept-Language
|
Request
|
Применимые языки. Используется для согласования передачи |
Authorization
|
Request
|
Учетные данные клиента, запрашивающего ресурс |
From
|
Request
|
Электронный адрес отправителя |
Host
|
Request
|
Имя/сетевой адрес [и порт] сервера. Если порт не указан, используется 80 |
If-Modified-Since
|
Request
|
Используется для выполнения условных методов (Если-Изменился...). Если запрашиваемый ресурс изменился, то он передается с сервера, иначе - из кэша |
Max-Forwards
|
Request
|
Представляет механиз ограничения количества шлюзов и прокси при использовании методов TRACE и OPTIONS
|
Proxy-Authorization
|
Request
|
Используется при запросах, проходящих через прокси, требующие авторизации |
Referer
|
Request
|
Адрес, с которого выполняется запрос. Этот заголовок отсутствует, если переход выполняется из адресной строки или, например, по ссылке из js-скрипта |
User-Agent
|
Request
|
Информация о пользовательском агенте (клиенте) |
Location
|
Response
|
Адрес перенаправления |
Proxy-Authenticate
|
Response
|
Сообщение о статусе с кодом 407 |
Server
|
Response
|
Информация о программном обеспечении сервера, отвечающего на запрос (это может быть как веб, так и прокси-сервер) |
Тело сообщения
Тело HTTP сообщения message-body
, если оно присутствует, используется для передачи сущности, связанной с запросом или ответом. Тело сообщения message-body
отличается от тела сущности entity-body
только в том случае, когда при передаче применяется кодирование, указанное в заголовке Transfer-Encoding
. В остальных случаях тело сообщения идентично телу сущности.
Заголовок Transfer-Encoding
должен отправляться для указания любого кодирования передачи, примененного приложением в целях гарантирования безопасной и правильной передачи сообщения. Transfer-Encoding
- это свойство сообщения, а не сущности, и оно может быть добавлено или удалено любым приложением в цепочке запросов/ответов.
Присутствие тела сообщения в запросе отмечается добавлением к заголовкам запроса поля заголовка Content-Length
или Transfer-Encoding
. Тело сообщения message-body
может быть добавлено в запрос только когда метод запроса допускает тело объекта entity-body
.
Все ответы содержат тело сообщения, возможно нулевой длины, кроме ответов на запрос методом HEAD
и ответов с кодами статуса 1xx (Информационные), 204 (Нет содержимого, No Content
), и 304 (Не модифицирован, Not Modified
).
HTTP-редиректы
Редиректы — способ перенаправить браузер на другой URL. Это похоже на то, как если бы вы пришли в магазин и там увидели надпись «мы переехали, вот наш новый адрес». После этого вы идете в магазин по новому адресу. Важно понимать, что редирект со стороны сайта лишь просит ваш браузер перейти на другой адрес, а не подсовывает вам другую страницу. Другими словами, технически редирект происходит на стороне клиента, а не сервера.
Проверка редиректов очень важна для проверки настроек префиксов домена типа www
и http
/https
.
У каждого домена обычно есть 4 варианта написания:
- http://domain.ru
- http://www.domain.ru
- https://domain.ru (обычно основной вариант)
- https://www.domain.ru
Редиректы можно проверить браузером через вкладку Network:
SSL шифрование
Принцип — передача только зашифрованных данных:
Типы SSL-сертификатов
- Платные (Comodo, Thawte, reg.ru)
Срок — 1 год или более
Стоимость — от 1500 руб/год - Let’s Encrypt (обычно мы используем именно LE)
Срок — 3 месяца
Стоимость — бесплатно
Нюанс: Wild Card сертификаты для поддоменов (*.flagstudio.ru). Доступны в LE только при DNS-аутентификации, то есть добавлении TXT-записи, которую нужно обновлять каждые 3 месяца. Для обновления используется API, которое есть не у всех DNS-провайдеров
Диагностика SSL
Если на сайте проблемы с SSL, то причина — в одном из двух:
- Что-то не так с сертификатом (кончился, выдан не на этот домен или самоподписанный)
- Страница запрашивает что-то по HTTP
На скриншоте видно, как посмотреть подробности о сертификате и наличие ошибок в странице. Конкретно на этом скриншоте показана вторая проблема, так называемая «mixed-content error», то есть часть контента прилетает по HTTP.
Для диагности SSL на вашем сайте вы также можете использовать онлайн-сервис https://www.ssllabs.com/ssltest/. Учтите, данные о сертификате, как и HTTP-редиректы, сильно кэшируются браузером.
Версии HTTP
Чтобы лучше понимать контекст конкретных изменений, которые HTTP/2 внес в HTTP/1.1, давайте ознакомимся с историей разработки и основными принципами работы каждого из релизов протокола.
HTTP/1
Разработанный Тимоти Бернерсом-Ли (Timothy Berners-Lee) в 1989 году в качестве стандарта связи для Всемирной паутины, HTTP – это протокол верхнего (прикладного) уровня, который обеспечивает обмен информацией между клиентским компьютером и локальным или удаленным веб-сервером. В этом процессе клиент отправляет текстовый запрос на сервер, вызывая метод (GET или POST). В ответ сервер отправляет клиенту ресурс, например, HTML-страницу.
HTTP/2
HTTP/2 появился как протокол SPDY, разработанный в основном в Google с целью снижения задержки загрузки веб-страниц такими методами, как сжатие, мультиплексирование и приоритизация. Этот протокол послужил шаблоном для HTTP/2, когда группа httpbis (это рабочая группа Hypertext Transfer Protocol) из IETF (Internet Engineering Task Force) объединила стандарт. Так в мае 2015 года случился релиз HTTP/2. С самого начала многие браузеры (включая Chrome, Opera, Internet Explorer и Safari) поддерживали эту попытку стандартизации. Частично благодаря этой поддержке с 2015 года наблюдается высокий уровень внедрения протокола, особенно среди новых сайтов.
Преимущества перед HTTP/1.1:
- Скорость. HTTP/2 — бинарный протокол, а HTTP/1.1 — текстовый
- Скорость. Мультиплексирование множества запросов в одном соединении TCP
- Скорость. Сжатие HTTP-заголовков
- Server Push. Принудительная отправка данных сервером в браузер
- Приоритеты запросов
Недостатки перед HTTP/1.1:
- Из-за «head-of-line blocking» на медленном интернете HTTP/1.1 работает быстрее
- Для работы HTTP/2 нужен SSL
Подробная статья с понятными картинками https://habr.com/ru/company/nix/blog/304518/