Протокол HTTP
99C# и .NET --- Сетевое программирование --- Протокол HTTP
HTTP — это упрощенный протокол прикладного уровня, который размещается поверх TCP и в основном известен как транспортный канал для World Wide Web и локальных интрасетей. Однако это классический протокол, который используется помимо гипертекста для многих других задач, например, в серверах доменных имен и системах распределенного управления объектами посредством своих методов запросов, кодов ошибок и заголовков. Сообщение HTTP представляется в MIME-подобном формате; оно содержит метаданные о сообщении (например, тип его содержания и длину) и информацию о запросе и ответе, например, метод, используемый для отправки запроса.
Существуют два основных компонента, от которых зависит Web: сетевой протокол TCP/IP и HTTP. Почти все события в Web происходят через HTTP, и этот протокол преимущественно используется для обмена документами (такими, как Web-страницы) в World Wide Web.
HTTP — это протокол приложения клиент-сервер, через который взаимодействуют две системы, обычно использующие соединение TCP/IP. HTTP-сервер — это программа, слушающая на порте машины входящие HTTP-запросы.
HTTP-клиент через сокет открывает соединение с сервером, отправляет сообщение с запросом на конкретный документ и ждет ответа от сервера. Сервер отправляет сообщение, содержащее код нормального или аварийного завершения, заголовки с информацией об ответе и (если запрос обработан успешно) требуемый документ. Общий формат HTTP-сообщения одинаков для запросов и ответов:
начальная-строка
заголовок-сообщения (или заголовки)
[тело-сообщения]
В сообщение может входить любое число заголовков, и каждый из них располагается на отдельной строке (т.е. каждому заголовку предшествуют символы возврата каретки и перевода строки). Тело сообщения присутствует необязательно, но если оно имеется, то отделяется от заголовков двумя последовательностями CRLF.
В протоколе HTTP используются постоянные и непостоянные соединения. Непостоянные соединения применяются по умолчанию в версии 1.0 HTTP, в то время как постоянные соединения ~ в версии HTTP 1.1. Соединение называют непостоянным (non-persistent connection), если любое TCP-соединение закрывается сразу же, как только сервер отправляет клиенту требуемый объект. Это означает, что соединение используется только для одного запроса и одного ответа и не сохраняется для других запросов и ответов.
В случае постоянных соединений сервер, отправив ответ, оставляет соединение открытым, и, таким образом, следующие запросы и ответы между теми же клиентом и сервером могут отправляться через это же самое соединение. Такое соединение сервер закрывает лишь после того, как оно не используется в течение некоторого интервала времени.
HTTP-заголовки
HTTP-сообщение состоит из начальной строки, за которой следуют набор заголовков, пустая строка и некоторые данные. Начальная строка задает действие, требуемое от сервера, тип возвращаемых данных или код состояния.
HTTP-заголовки можно подразделить на три крупные категории: заголовки, посылаемые в запросе, заголовки, посылаемые в ответе, и те, которые можно включать как в запросы, так и в ответы. Заголовки запросов указывают возможности клиента, например, типы документов, которые может обработать клиент, в то время как заголовки ответов предоставляют информацию о возвращенном документе.
Заголовки запросов
К числу наиболее важных HTTP-заголовков, которые можно включать в запросы, но нельзя включать в ответы, относятся:
- Заголовок Accept
Это список MIME-типов, принимаемых клиентом, в формате тип/подтип. Элементы списка должны разделяться запятыми:
Accept: text/html, image/gif, */*
Элемент */* указывает, что все типы будут приняты и обработаны клиентом. Если тип запрошенного файла не может быть обработан клиентом, возвращается ошибка HTTP 406 "Not acceptable" (недопустимо).
- Заголовок From
Указывает адрес электронной почты в Интернете учетной записи пользователя, под которой работает клиент, направивший запрос:
From: alexerohinzzz@gmail.com
- Заголовок Referer
Позволяет клиенту указать адрес (URI) ресурса, из которого получен запрашиваемый URI. Этот заголовок дает возможность серверу сгенерировать список обратных ссылок на ресурсы для будущего анализа, регистрации, оптимизированного кэширования и т.д. Он также позволяет прослеживать с целью последующего исправления устаревшие или введенные с ошибками ссылки:
Referer: http://www.professorweb.ru
- Заголовок User-Agent
Представляет собой строку, идентифицирующую приложение-клиент (обычно браузер) и платформу, на которой оно выполняется. Общий формат имеет вид: программа/версия библиотека/версий, но это не неизменный формат:
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17
Эта информация может использоваться в статистических целях, для отслеживания нарушений протокола и для автоматического распознавания клиента. Она позволяет приспособить ответ так, чтобы не нарушить ограниченные возможности конкретного клиента, например неспособность поддерживать HTML-таблицы.
Заголовки ответов
В ответы могут включаться следующие заголовки:
- Заголовок Content-Type
Используется для указания типа данных, отправляемых получателю или, в случае метода HEAD, тип данных, который был бы отправлен в ответ на запрос GET:
Content-Type: text/html
- Заголовок Expires
Представляет собой момент времени, после которого информация в документе становится недостоверной. Клиенты, использующие кэширование, в частности прокси-серверы, не должны хранить в кэше эту копию ресурса после заданного времени, если только состояние копии не было обновлено более поздним обращением к исходному серверу:
Expires: Fri, 19 Aug 2012 16:00:00 GMT
- Заголовок Location
Определяет точное расположение другого ресурса, к которому может быть перенаправлен клиент. Если это значение представляет собой полный URL, сервер возвращает клиенту "redirect" для непосредственного извлечения указанного объекта:
Location: http://www.samplesite.com
Если ссылка на другой файл относится к серверу, должен указываться частичный URL.
- Заголовок Server
Содержит информацию о программном обеспечении, используемом исходным сервером для обработки запроса:
Server: Microsoft-IIS/7.0
Общие заголовки
Несколько заголовков могут включаться как в запрос, так и в ответ, например:
- Заголовок Date
Используется для установки даты и времени создания сообщения:
Date: Tue, 16 Aug 2012 18:12:31 GMT
- Заголовок Connection
В НТТР/1.0 мы могли использовать в запросе заголовок Connection, указывая, что хотим сохранить соединение после отправки ответа. Теперь такое поведение принято по умолчанию, и в HTTP/1.1 можно использовать заголовок Connection, чтобы указать, что постоянное соединение не нужно:
Connection: close
HTTP-запросы
Каждый клиент посылает запрос, и сервер на него отвечает. Все запросы и ответы состоят из трех частей, а именно: строки запроса или ответа, секции заголовков и тела сущности (любого содержания, отправляемого вместе с сообщением, например, страницы HTML для отображения в браузере или данных формы, пересылаемых на сервер).
Клиент связывается с сервером в назначенном номере порта (по умолчанию равном 80) и запрашивает у сервера документ, задавая HTTP-команду, называемую методом, за которой следует адрес документа и номер версии HTTP. Клиент также отправляет серверу необязательную информацию в заголовках, чтобы сообщить серверу о своей конфигурации и приемлемых для него форматах документов. Информация заголовка дается в одной строке вместе с именем и значением заголовка. После заголовков клиент посылает пустую строку. Затем клиент отправляет дополнительные данные. Это могут быть данные формы, отправляемые на сервер методом POST, или файл, копируемый на сервер методом PUT.
Запросы клиентов подразделяются на три секции. Первая строка сообщения всегда должна содержать HTTP-команду, называемую методом, за которой следует URI, идентифицирующий файл или ресурс, запрашиваемый клиентом, и номер версии HTTP:
GET /default.aspx HTTP/1.1
Теперь исследуем каждую из этих секций. Метод — это HTTP-команда, начинающая первую строку запроса клиента. Метод информирует сервер о цели запроса клиента. Для HTTP определены семь методов: GET, HEAD, POST, OPTIONS, PUT, DELETE и TRACE, но HTTP-серверы могут также реализовать методы расширения, не определенные протоколом HTTP. Заметим, что названия методов зависят от регистра клавиатуры, поэтому, например, слово get не будет распознано как допустимый метод.
Метод GET используется для запроса информации, расположение которой на сервере определяется заданным URI. Этот метод широко применяется браузерами, чтобы извлекать документы для просмотра. Результат запроса GET генерируется разными способами. Это может быть файл, доступный с сервера, вывод программы, вывод, полученный на устройстве, и т. д.
Когда клиент в своем запросе использует метод GET, сервер отправляет ответ, содержащий строку состояния, заголовки и метаданные. Если сервер не может обработать запрос из-за ошибки или отсутствия авторизации, он отправляет объяснение в текстовом виде, помещая его в ответе в секцию данных.
Секция тела о сути запроса GET всегда остается пустой. Запрошенный клиентом ресурс (файл или программа) идентифицируется по его полному пути на сервере. Любая дополнительная информация, например, значения из формы, которую клиенту нужно отправить серверу, присоединяется вслед за URI как строка запроса:
GET /default.aspx?name=Alex HTTP/1.1
Метод HEAD функционально аналогичен методу GET, не считая того, что сервер ничего не помещает в секцию данных ответа. Методом HEAD запрашивается только заголовочная информация по файлу или ресурсу. Для запроса HEAD HTTP-сервер должен отправить в заголовках ту же информацию, которую он бы отправил в ответ на запрос GET. Данный метод используется, если клиенту нужна информация о документе, но не нужно получать сам документ.
Метод POST позволяет отправить данные серверу в клиентском запросе. Эти данные посылаются программе обработки данных, к которой у сервера есть доступ. Метод POST может использоваться для многих приложений, например, для обеспечения входных данных сетевых служб, программ интерфейса командной строки и т.д. Данные отправляются на сервер в секции тела сути клиентского запроса. Обработав запрос POST и заголовки, сервер передает это тело программе, указанной в URI.
В методе OPTIONS запрашивается информация о поддержке HTTP на Web-cepвeре. Метод OPTIONS может применяться с URL, чтобы извлечь информацию о конкретном документе или, с групповым символом *, чтобы получить информацию о возможностях сервера в целом. Информация возвращается в заголовках ответа.
HTTP-ответы
Ответ сервера на запрос клиента также подразделяется на три части. Первая строка—это строка ответа сервера, содержащая номер версии HTTP, номер, указывающий состояние запроса, и краткую фразу, описывающую это состояние. Далее следует информация заголовков, за ней — пустая строка и тело сущности (которое может быть пустым, например, в ответах на запросы HEAD и OPTIONS).
В качестве версии HTTP указывается та версия, которую сервер использует в ответе. Код состояния представляет собой трехбайтовое число, указывающее результат обработки сервером запроса клиента. Описание, следующее за кодом состояния, просто дает удобное для восприятия пользователем значение кода состояния. Хотя существует несколько определенных кодов состояния, сервер вправе устанавливать дополнительные коды. Некоторые наиболее распространенные определенные коды приводятся в следующей таблице:
Код | Описание |
---|---|
200 | ОК — запрос был получен и обработан |
301 | Ресурс перемещен постоянно |
302 | Ресурс перемещен временно |
400 | Неверный запрос—сообщение с запросом имеет некорректный формат |
401 | Несанкционированный доступ — у пользователя нет прав для доступа к запрошенному документу. |
402 | Ресурс доступен за плату |
408 | Тайм-аут запроса |
500 | Внутренняя ошибка сервера—ошибка помешала HTTP-серверу обработать запрос |
После строки состояния сервер отправляет клиенту в заголовках информацию о себе и запрошенном документе. Заголовки завершаются пустой строкой (т.е. двумя идущими подряд последовательностями CRLF).
Если клиент запрашивал данные и запрос обработан успешно, эти данные будут отправлены в теле сущности после заголовков ответа. Они могут представлять собой копию запрошенного файла или содержание, сгенерированное динамически, например страницу ASP.NET или сценарий на стороне сервера. Если запрос клиента не выполнен, могут быть предоставлены дополнительные данные объясняющие, почему сервер не смог выполнить этот запрос.
В HTTP 1.0 сервер, завершив отправку запрошенных данных, отсоединяется от клиента и транзакция на этом заканчивается, если только не был отправлен заголовок Connection: Keep-Alive. Однако в HTTP 1.1 сервер должен поддерживать соединение, позволяя клиенту делать дополнительные запросы, даже если заголовок Connection не был отправлен. Если не нужно такое поведение, следует отправить заголовок Connection: close, который указывает, что после отправки ответа соединение должно быть закрыто.