Протокол HTTP: все что нужно для веб-разработки. Часть 1

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

Основы HTTP

HTTP позволяет двум хостам обмениваться данными. При этом, как уже было сказано, протокол не сохраняет состояние между “запрос-ответами”. Обмен происходит с помощью TCP/IP, но, на самом деле, может быть использован любой другой надежный транспортный механизм. Чаще всего используется 80-ый порт, но и тут тоже могут быть использованы другие порты.

Обмен данными происходит между двумя участниками. Один традиционно называют сервером, а другой клиентом. Процесс “общения” основан на паре “запрос-ответ”. Клиентская сторона формирует HTTP запрос, который обслуживает серверная сторона и формирует HTTP ответ.

Текущая версия протокола HTTP/1.1. Она представляет из себя дополненную версию 1.0 с некоторыми серьезными улучшениями такими как persistent connectionschunked transfer-coding и fine-grained caching headers

URL

В основе обмена данными лежит тело запроса, которое отправляется с помощью URL (универсальный локатор ресурса). Более подробно структура типичного URL обозначена на рисунке:

http1-url-structure

Протокол обычно http, но может быть и https (для безопасной связи). По умолчанию используется 80-ый порт, но любой другой может быть указан, как показано выше (1234). Путь к ресурсу является локальным путем ресурса в рамках сервера.

Методы

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

  • GET - получает существующий ресурс. При этом URL содержит всю необходимую информацию, чтобы найти и вернуть ресурс.
  • POST - создать новый ресурс. При этом POST запрос обычно содержит всю необходимую информацию для создания нового ресурса.
  • PUT - обновить существующий ресурс. При этом PUT запрос содержит все необходимые данные для обновления ресурса.
  • DELETE - удалить существующий ресурс.

Перечисленные методы являются наиболее популярными и многие фрэймворки и инструменты явно реализуют их. Но иногда PUT и DELETE методы рассматриваются как специализированные версии POST (при этом в запросе по-прежнему должны содержаться все необходимые для ресурса данные). Кроме того, существуют и менее популярные методы:

  • HEAD - похоже на GET с той лишь разницей, что отсутствует тело запроса. Обычно этот метод используется для получения заголовков сервера, чтобы проверить изменился ли ресурс (на основании timestamps).
  • TRACE - используется для того, чтобы получить все “прыжки”, которые совершает запрос по пути “туда и обратно”. В заголовок Via, при этом,  попадает IP или DNS любого промежуточного прокси или шлюза.
  • OPTIONS - используется для того, чтобы выяснить серверные возможности. На клиентской стороне это может помочь модифицировать запрос на основе того, что поддерживает сервер.

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

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

1xx: Информационные сообщения

Этот класс состояний был добавлен в HTTP/1.1 и носит условный характер. Например, сервер может послать заголовок Expect: 100-continue, что будет означать для клиента сигнал к продолжению отправки оставшейся части запроса. Если запрос отправлен полностью, то клиент проигнорирует этот заголовок. HTTP/1.0-клиенты проигнорирует его в любом случае.

2xx: Успешно

Эта группа состояний говорит клиенту, что все прошло хорошо и запрос успешно обработан. Чаще всего встречается код 200 OK. В случае GET-метода вместе с таким кодом в теле HTTP ответа отправляется запрашиваемый ресурс. Существует еще и менее распространенные и известные коды:

  • 202 Принято:  запрос был принят, но возможно ресурс не был включен в ответ. Это полезный код для асинхронной обработки на серверной стороне, т.к. позволяет отправлять информацию для мониторинга процесса.
  • 204 Нет содержимого: в теле ответа не содержится ничего.
  • 205 Сброс содержимого: сообщает клиенту, что необходимо сбросить введенные пользователем данные. В теле ответа при этом ничего не передается.
  • 206 Частичное содержимое: сообщает, что ответ содержит лишь часть запрашиваемой информации. Заголовок Content-Range в таком случае содержит точный диапазон данных в байтах. 

3xx: Перенаправление

Коды этого диапазона означают, что клиенту необходимо сделать другой запрос, чтобы получить требуемые ресурс. Наиболее частый сценарий – запрос на другой URL, но могут быть и другие значения кодов:

  • 301 Перемещено навсегда:  запрашиваемый ресурс теперь расположен на другом URL.
  • 303 Смотреть другое: временное перемещение ресурса на новый URL. В заголовке Location содержится временный URL.
  • 304 Не изменялось: сервер определил, что запрашиваемый ресурс не изменился, и клиенту стоит воспользоваться его локальной копией. Это утверждение основывается на ETag информации, которую отправляет клиент. ETag представляет собой хэш содержимого. Сервер сравнивает клиентский хэш и свой (на основе запрашиваемого содержимого) и выясняет изменился ресурс или нет.

4xx: Ошибка клиента

Эти коды используются, когда сервер полагает, что в результате запроса клиент допустил ошибку, например, запрашивает несуществующий ресурс. Наиболее распространенный код – 404. С ним сталкивались, пожалуй, все. Он говорит клиенту, что запрошенный ресурс не существует на сервере. Кроме того, существуют и другие коды:

  • 400 Плохой запрос:  запрос был сформирован неверно.
  • 401 Неавторизован: запрос требует от клиента авторизации. Клиент может повторить запрос с заголовком Authorization. В случае, если такой заголовок уже был отправлен, то это означает, что переданные данные заголовка неверны.
  • 403 Запрещено: сервер отказал в доступе к ресурсу.
  • 405 Метод не разрешен: в запросе указан неверный метод, либо сервер не поддерживает указанный клиентом метод.
  • 409 Конфликт: сервер не может обработать запрос, т.к. клиент пытается изменить ресурс, которые новее, судя по клиентскому timestamp. Обычно такое возникает при запросе c PUT методом, при совместном доступе к ресурсу несколькими клиентами.

5xx: Ошибка сервера

Этот класс состояний говорит о серверной ошибке в процессе обработки клиентского запроса. Чаще всего можно увидеть 500 Внутренняя ошибка сервера, но кроме этого кода есть и другие:

  • 501 Не реализовано:  сервер не поддерживает функциональности, необходимой для обработки запроса.
  • 503 Сервис недоступен: чаще всего означает, что внутренняя система сервера либо не обрабатывает запросы по техническим причинам, либо сервер перегружен.

 Форматы запроса и ответа

Обратим внимание на то, из чего же собственно состоят запросы. Как ясно из вышесказанного, в первую очередь нужны 3 компонента: URL, метод, код состояния.

HTTP спецификация определяет более строгое описание структуры запроса или ответа:

Обязательным условием является наличие “новой” строки между секцией заголовок и тела. Запрос может содержать несколько заголовков, которые классифицируются следующим образом:

  • general заголовки(применимы как в случае запроса, так и в случае ответа)
  • request specific заголовки
  • response specific заголовки
  • entity заголовки

Тело, в свою очередь, может содержать либо полный набор данных, либо только часть в случае, если используется заголовок Transfer-Encoding: chunked 

General заголовки

Существует несколько общих заголовков, которые могут быть использованы как в запросе, так и в ответе.

Некоторые из этих заголовков уже были упомянуты выше, рассмотрим их подробнее:

  • Via заголовок используется в запросе с методом TRACE и содержит все промежуточные прокси и шлюзы (а именно их IP или DNS)
  • Pragma может использоваться для добавления информации о специфике реализации. Например, самым часто распространенным применением является Pragma: no-cache, что само по себе идентично Cach-Control: no-cache в HTTP/1.1.
  • Date заголовок используется для хранения timestamp запроса или ответа.
  • Upgrade используется для переключения  на более новую версию протокола.
  • Transfer-Encoding обычно используется для того, чтобы разбить ответ на несколько более мелкий частей с помощью значения Transfer-Encoding: chunked. Это новый в HTTP/1.1 заголовок, который позволяет “транслировать” серверный ответ клиенту по частям вместо одного большого блока данных.

Entity заголовки

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

Все заголовки с префиксом Content- дают информацию о структуре, размере, кодировке тела содержимого.

Заголовок Expires содержит временную метку, когда содержимое будет считаться устаревшим. В случае, если необходимо обозначить содержимое, как “никогда не устареет”, обычно устанавливают временную метку на год вперед. Заголовок Last-Modified содержит временную метку последнего изменения содержимого.

Формат запроса

Формат запроса имеет такую же структуру, как было показано выше, но с некоторыми особенностями. А именно, ключевая особенность заключается в строке запроса:

SP означает пробел-разделитель между элементами строки. HTTP-Version имеет значение HTTP/1.1, а далее следует перевод на новую строку. Таким образом, типичный вид запроса может выглядеть так:

Стоит обратить внимание, что после строки запроса следует целый ряд заголовков запроса, например обязательный для HTTP/1.1 заголовок Host. В данном примере метод GET подразумевает отсутствие тела запроса, а вот в случае POST в теле могут содержатся некоторые данные.

Заголовки запроса используются также, как и другие. Все неизвестные заголовки распознаются как entity заголовки. Список всех возможных заголовков запроса приведен ниже:

Заголовки с префиксом Accept передают допустимые кодировки, язык, медиа-тип, которые способен принимать клиент. From, Host, Referer, User-Agent – группа заголовков содержит информацию о клиенте, инициирующем запрос. Заголовки с префиксом If- позволяют сделать запрос в определенной степени условным, и сервер возвращает клиенту ресурс только в случае, если все условия выполнены. Иначе будет возвращен код состояния 304 (см. выше). Условия могут базировать, например, на временных метках или ETag хэше.

Формат ответа

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

HTTP-Version содержит HTTP/1.1, Status-Code – код состояния в числовом формате, Reason-Phrase – код состояния в словесной форме. Таким образом, типичная статусная строка имеет вид:

Характерных для ответа заголовков не так много:

Age – это возраст сообщения (в секундах), когда оно было сгенерировано на сервере. ETag – это MD5 хэш содержимого, который передается в ответе, и он используется для определения внесенных  изменений. Location используется для перенаправления клиента на новый URL. Server содержит данные о сервере, который генерирует ответ.

 

Источник

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">