Протокол HTTP
 

Что такое протокол HTTP и для чего он нужен, я думаю расказывать не нужно, поэтому сразу приступим к более подробному рассмотрению. Какое отношение HTTP протокол имеет к Perl? Да самое прямое. Без знания HTTP протокола, нельзя написать практически никакого CGI скрипта.
Итак, договоримся о терминах.
Веб-сервер - програмное обеспечение, которое следит за 80 (возможны и другие варианты, но данный наиболее популярен) портом и в случае обнаружения запроса, выдает некоторую информацию (сообщение об ошибке, html документ).
Клиент - программное обеспечение осуществляющее подключение к 80 порту сервера и посылающее туда запрос.

Помимо выдачи статичных документов, веб-серверы умеют выдавать результаты работы скрипта. т.е. если клиент запрашивает документ, который на самом деле является CGI скриптом, то веб-сервер запускает этот скрипт на выполнение, а всю информацию полученную со стандартного выхода скрипта, перенаправляет клиенту.
В процессе прочтения данного документа, вам наверно захочется попробовать все предложенные примеры. Используйте для этого любой telnet клиент. Просто соединитесь с 80 портом сервера, на котором расположен ваш любимый сайт.
Взаимодействие, между веб-сервером и клиентом просто до неприличия. Клиент посылает запрос состоящий из заголовка и (иногда) тела, а веб-сервер выдает ответ, который так же состоит из заголовка и тела. Рассмотрим более детально, как же выглядят эти запросы и ответы.

Любой запрос начинается строкой:
 МЕТОД РЕСУРС HTTP/версия 

МЕТОД - один из поддерживаемых веб-сервером методов. Наиболее распространены:
GET - в этом случае выдается запрошенный ресурс. Самый старый и самый распространенный метод.
HEAD - в этом случае, выдается только заголовок документа. Из заголовка можно узнать существует ли документ, его размер и еще некоторую информацию, о которой ниже. Данный метод, как правило, используется для проверки ссылок и кеширующими системами.
POST - аналогичен методу GET, но не только запрашивает ресурс, но и передает ему некоторую информацию. Если ресурс - CGI скрипт, то информация поступает на его стандартный ввод. Метод GET тоже умеет передавать информацию для CGI скриптов, но передает он ее в самом имени ресурса. Дело в том, что если мы вызовем CGI скрипт таким образом:

 script.cgi?ПАРАМЕТРЫ 

то веб-сервер запустит на выполнение script.cgi, а тот в свою очередь сможет заполучить ПАРАМЕТРЫ. А вот о том, откуда он их получит, позже.

Кроме вышеперечисленных методов, существуют еще методы PUT - для сохранения данных в указанном ресурсе и DELETE - для удаления указанного ресурса. Как правило они не поддерживаются веб-серверами, сами понимаете почему.
Теперь пример запроса:

 GET /~user/cgi-bin/test.pl HTTP/1.0 

Это конечно самый простой пример. Обычно, запрос выглядит гораздо сложнее и состоит из нескольких строк. Чтобы веб-сервер знал, что ввод данных закончен, нужно послать ему пустую строку. Т.е в данном примере, нужно нажать Enter два раза (один раз - переход на новую строчку, второй раз - пустая строка).
Если вы запрашиваете главную страницу сайта (т.е. в браузере это www.perl.ru) запрос будет выглядеть так:

 GET / HTTP/1.0 

Практически все переданные данные можно узнать непосредственно в скрипте на перле. Для этого служит массив %ENV, в котором хранятся так называемые переменные среды CGI. Например:

 $ENV{REQUEST_METHOD} = GET $ENV{QUERY_STRING} = те самые параметры (script.cgi?параметры) 
Узнать все пременные очень просто:
 foreach (keys %ENV){ print "$_ = $ENV{$_}\n"; } 
Какую же еще информацию, мы можем передавать веб-серверу?

Поле Пример Описание
Date: Date: Sun, 30 Dec 2000 23:59:59 GMT Дата запроса.
MIME-version: MIME-version: 1.0 Версия MIME.
Pragma: Pragma: no-cache Информация для шлюзов и прокси-серверов.
Authorization: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== Информация для авторизации.
From: From: Pupkin@mail.ru e-mail пользователя браузера.
If-Modified-Since: If-Modified-Since: Sun, 30 Dec 2000 23:59:59 GMT Используется при методе GET. Документ возвращается только в том случае, если он изменился с указанного момента. Как правило браузер, запрашивает документ подобным образом, если копия документа содержится у него в кеше. И соответственно выдает пользователю информацию из кеша или обновленный документ.
Referer: Referer: http://www.per.ru/links.html URL предшествующего ресурса. Именно по нему на некоторых сайтах определяется, насколько хорошо их рекламирует тот или иной ресурс.
User-Agent: User-Agent: Mozilla/5.0 Имя клиента. Может стоять что угодно, но некоторые, особенно гадкие сервера, не выдают страницы "не браузерам".
Host: Host: vasya.narod.ru Имя хоста. Дело в том, что в сети существует очень большое количество виртуальных серверов, т.е. серверов с разными именами, но одним IP адресом. Именно по этой переменной веб-сервер определяет какую же информацию вам дать.
Accept: Accept: text/html Указывает серверу, выдавать только данные указанного типа.


Вот основные и наиболее часто используемые данные, передаваемые веб-серверу.
Теперь пара примеров запросов:
 GET /~user/cgi-bin/test.cgi?name=Vasily&age=18 HTTP/1.0 User-Agent: Mozilla/5.0 
И тоже, но методом POST
 POST /~user/cgi-bin/test.cgi HTTP/1.0 User-Agent: Mozilla/5.0 Accept: text/html Accept: image/gif Content-Type: application/x-www-form-urlencoded Content-Length: 18 name=Vasily &age=18 
Теперь рассмотрим, что же отвечает веб-сервер. Ответ веб-сервера выглядит следующим образом:
 HTTP/ВЕРСИЯ КОД_ОТВЕТА ФРАЗА_ОТВЕТА 
КОД_ОТВЕТА - 3-хзначное число. Указывает что все прошло успешно (200) или код ошибки.
ФРАЗА_ОТВЕТА - Тот же код но по-русски (шучу, по-английски)
Пример:
 HTTP/1.1 200 OK 

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

 Location: http://www.perl.ru/ 

Она указывает браузеру, что нужно немедленно идти по этому адресу, что собственно они все успешно и делают. Далее я перечислю коды ответа браузера и их значения.

Обязательно должна присутствовать строчка:
 Content-Type: text/html 
указывающая тип переданных данных.

Ну и напоследок, список кодов возвращаемых веб-серверами и их значений

 Код статуса   Значение 
200 OK
201 Успешная команда POST
202 Запрос принят
203 Запрос GET или HEAD выполнен
204 Запрос выполнен но нет содержимого
300 Ресурс обнаружен в нескольких местах
301 Ресурс удален навсегда
302 Ресурс отсутствует временно
304 Ресурс был изменен
400 Плохой запрос от клиента
401 Неавторизованный запрос
402 Необходима оплата за ресурс
403 Доступ Запрещен
404 Ресурс не найден
405 Метод не применим для данного ресурса
406 Недопустимый тип ресурса
410 Ресурс Недоступен
500 Внутренняя ошибка сервера
501 Метод не выполнен
502 Неисправный шлюз либо перегруз сервера
503 Сервер недоступен/тайм-аут шлюза
504 Вторичный шлюз/тайм-аут сервера
 
Автор: Philip A. Koryaka
 
Оригинал статьи: http://woweb.ru/publ/58-1-0-319