3 июл. 2009 г.

Руководство начинающего веб-разработчика. Протокол HTTP.

Краткая теория

Основным протоколом передачи данных в World Wide Web является HTTP (англ. Hyper Text Transfer Protocol — протокол передачи гипертекста). Для тех, кто не знает: сетевой протокол это набор соглашений и правил, позволяющий подключенным к сети устройствам осуществлять установление соединения и обмен данными.

HTTP реализует технологию «клиент-сервер», то есть, в нем присутствуют выделенные клиент, которые отправляет запрос, и сервер, который этот запрос обрабатывает и отправляет клиенту ответ. Наиболее распространенным типом HTTP-клиента является браузер, например Mozilla Firefox, Opera или Microsoft Internet Explorer.

Для указания адреса в HTTP используется URI (Uniform Resource Identifier — унифицированный идентификатор ресурса) со схемой http (схема в URI это часть до первого двоеточия). Видели их все, адреса страниц вроде http://example.com/pages/index.html это они и есть.

Протокол HTTP не сохраняет состояние. Это значит, что каждая пара запрос-ответ независима от предыдущих, и о предыдущих запросах протокол ничего не знает.

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

Формат сообщения

Любое сообщение имеет вид:

Стартовая строка
Заголовки

Тело сообщения

Стартовая строка будет разной для запроса и ответа. Для запроса она имеет вид: Метод URI HTTP/версия. Для ответа же: HTTP/версия код_состояния пояснение. Самая распространенная на данный момент версия это 1.0, многие сервера поддерживают 1.1. В разработке находится версия HTTP-ng (next generation).

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

Методы запроса

Метод это указание на то, какую операцию следует совершить с ресурсом. Название метода чувствительно к регистру и должно быть записано заглавными буквами.

Спецификация протокола включает в себя следующие методы:

  • OPTIONS — используется для определения возможностей веб-сервера или параметров соединения для конкретного ресурса.
  • GET — получение содержимого ресурса. Позволяет указывать параметры запроса в виде http://example.org/resource?variable1=value1&variable2=value2… Этот метод позволяет также получить только часть содержимого или запросить его только в случае выполнения некоторого условия (например, только если оно изменялось)
  • HEAD — похож на GET, но в ответе отсутствует тело сообщения. Этот метод используют для получения метаданных, например для проверки времени последнего изменения ресурса или проверки его существования.
  • POST — применяется для передачи данных пользователя на сервер.
  • PUT — осуществляет загрузку содержимого ресурса на сервер.
  • PATCH — тот же PUT, но применяется к части ресурса.
  • DELETE — удаляет указанный ресурс с сервера.
  • TRACE — возвращает ответ в таком виде, чтобы можно было отследить, что в него добавляют промежуточные сервера.
  • CONNECT — используется с серверами, поддерживающими туннельный режим SSL.
  • LINK — устанавливает связь ресурса с другими.
  • UNLINK — удаляет связь ресурса с другими.

HTTP-сервер обязан поддерживать только методы GET и HEAD, реализация остальных не обязательна. В реальности наиболее часто используются GET, HEAD и POST, остальные применяются крайне редко.

Заголовки

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

Заголовки бывают четырех типов:

  • Общие заголовки — могут быть как в запросе, так и в ответе.
  • Заголовки запроса — включаются только в запрос
  • Заголовки ответа — включаются только в ответ.
  • Заголовки сущности — относятся к отдельной сущности сообщения.

Последний тип заголовков применяется только при передаче множественного содержимого. Посмотрим на некоторые распространенные заголовки:

Заголовки запроса

Host: имя хоста
В этом заголовке указывается имя компьютера, с которого отправлен запрос. Может содержать ip-адрес или доменное имя.

Accept: MIME-тип
Описывает допустимый формат ответа в виде типа MIME. Например text/html, или image/png.

User-agent: название и версия клиента
В нем указывается тип и версия использованного клиента. Например Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; v:1.7.5) Gecko/20041202 Firefox/1.0

Заголовки ответа

Server: название сервера
Указывает тип и версию программного обеспечения сервера. Например Apache/2

Last-Modified: дата
Содержит дату последней модификации содержимого ресурса.

Content-Type: тип MIME
Содержит формат тела ответа.

Content-Length: размер в байтах
Содержит размер тела сообщения в байтах.

Существует много других заголовков, например для указания того, что нужно получить только часть содержимого, управления кэшированием и многих других целей. Все они описаны в спецификациях протокола.

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

Код состояния используется для указания результата выполнения запроса. По своему содержанию они делятся на несколько классов.

Информационные (Informational), значения вида 1xx
Они информируют клиента о процессе передачи. Ответ с таким кодом содержит только стартовую строку и может быть, несколько специфичных заголовков.
Успешный результат (Success), значения вида 2xx.
Сообщают об успешном выполнении запроса, ответ может содержать тело сообщения. Примеры: 200 Ok — запрос выполнен успешно.
Перенаправление (Redirection), значения вида 3xx.
Сообщают о том, что для получения ресурса нужно совершить другой запрос, с указанием URI ресурса. Пример: 301 Moved permanently — ресурс был окончательно перемещен на другой адрес.
Ошибка клиента (Client error), значения вида 4xx.
Сообщают о том, что клиент отправил ошибочный запрос. Например 404 Not found — Ресурс не найден, или 401 Bad request — запрос сформирован неверно.
Ошибка сервера (Server error), значения вида 5xx.
Информируют об ошибке на сервера. Например 500 Internal server error — внутренняя ошибка сервера, вы неоднократно столкнетесь с ней при разработке собственных приложений :)

Практическая часть

Вооружившись этими теоретическими знаниями, мы наконец сможем увидеть, что именно происходит в тот момент, когда пользователь просматривает в браузере веб-сайты.

Сперва мы сформируем простейший HTTP-запрос и поосмотрим, что на него ответит сервер. Чтобы сделать это, запустите утилиту telnet (или лучше netcat, если вы используете UNIX). Если вы используете UNIX, вы знаете что делать; под Windows: Пуск, Выполнить, cmd. Введите команду telnet w3.org 80.В качестве примера взят сервер w3.org, на котором находится сайт организации World Wide Web Consortium, которая занимается стандартами WWW. Теперь формируем запрос:

[user@host ~]$telnet w3.org 80
Написанное курсивом писать не надо, это пояснения.
Trying 128.30.52.45...
Connected to w3.org.
Escape character is '^]'.
Писать начинаем отсюда. Все предыдущее это вывод программы.
GET / HTTP/1.0 Это стартовая строка.
Host: ваш ip-адрес (хотя можно ввести любой адрес или домен) Это заголовок.

После этого нажмите Enter два раза и вы получите в ответ что-то вроде

HTTP/1.1 200 OK Так выглядит стартовая строка ответа.
Date: Fri, 03 Jul 2009 07:21:15 GMT Вот заголовок.
Server: Apache/2 Еще один заголовок, это заголовок ответа.
Content-Length: 829
Connection: close
Content-Type: text/html;charset=ISO-8859-1

Тело ответа, здесь не приведено для экономии места

Исходя из написанного выше, мы можем понять что запрос был выполнен успешно (200 Ok), в качестве веб-сервера использован Apache, тело ответа имеет размер 829 байт и формат HTML.

В качестве эксперимента попробуйте выполнить запросы с другими методами, например HEAD / HTTP/1.0 или DELETE / HTTP/1.0. Посмотрим на заголовки ответа на последний запрос:

HTTP/1.1 405 Method Not Allowed
Date: Fri, 03 Jul 2009 08:47:22 GMT
Server: Apache/2
Allow: GET,HEAD,POST,OPTIONS,TRACE
Content-Length: 224
Connection: close
Content-Type: text/html; charset=iso-8859-1

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

Изображаем веб-сервер

Теперь мы посмотрим на процесс в другой стороны, а именно со стороны сервера. Все, что я здесь описываю, относится к UNIX-системам, сделать это под Windows стандартными средствами не получится. Со временем найду средства или напишу свою программу, пока для экспериментов можете использовать любой live-cd с Linux.

Простейший способ получать данные от программ по сети предоставляет утилита netcat. Выполните команду netcat -lp 7268 Эта команда запустит процесс, слущающий на порту 7268 (взят случайный порт, не используемый ничем из стандартных приложений). Запустить ее дадут только от имени суперпользователя, поэтому зайдите под учетной записью root или используйте sudo ( sudo netcat -lp 7268 ).

Теперь откройте ваш браузер и введите адрес http://localhost:7268. В выводе netcat появится что-то вроде:

[user@host ~]$sudo netcat -lp 7268
GET / HTTP/1.1
Host: localhost:7268
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.0.9) Gecko/2009041500 SUSE/3.0.9-0.1 Firefox/3.0.9
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Похоже на то, что мы писали серверу в предудщем параграфе? Это браузер отправил нам GET-запрос. Теперь мы можем на него ответить.

HTTP/1.0 200 Ok
Server: netcat
Content-type: text/html

Hello!

Нажмите Enter после ввода последней строки. Теперь загляните в окно браузера, чтобы увидеть там свой ответ.

Заключение

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

Ссылки

Комментариев нет:

Отправить комментарий