Common Gateway Interface (Общий интерфейс шлюза)

В предыдущих разделах уже неоднократно подчеркивалось, что динамический сайт можно создать только в том случае, если используются какие-то программные средства. Если эти средства установлены на сервере (что имеет место в большинстве случаев), то должен существовать и механизм взаимодействия HTTP-сервера с подключаемыми (вызываемыми) программами, обрабатывающими запросы пользователей. И такой механизм, естественно, существует. Он называется Common Gateway Interface (в переводе - общий интерфейс шлюза) или кратко CGI. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть CGI-сценарием или CGI-скриптом, хотя она может быть написана на любом языке программирования, который может работать со стандартными устройствами ввода/вывода. Чаще всего для создания CGI-программ используются PERL, Си или shell-скрипты (если используется UNIX-сервер).

Все CGI-скрипты, как правило, помещают в каталог cgi-bin сервера, но это необязательно: скрипт может располагаться где угодно, но при этом большинство веб-серверов требуют специальной настройки. В HTTP-сервере Apache, например, такая настройка может производиться при помощи общего файла настроек httpd.conf или с помощью файла .htaccess в том каталоге, где содержится этот скрипт. Также Apache позволяет запускать все скрипты, имеющие расширение .cgi.

Как подчеркивалось в предыдущих разделах, создание динамических страниц обусловлено необходимостью обеспечения взаимодействия с посетителем вашего сайта. Следовательно сразу же возникает проблема получения сведений о том, чего же хочет пользователь, и проблема передачи этих данных от браузера пользователя Интернет-серверу (или той программе, которая будет запрос пользователя обрабатывать). Чтобы понимать, как это происходит, надо хотя бы в общих чертах представлять себе как устроен протокол HTTP.

Базовые сведения о протоколе HTTP

Взаимодействие сервера с клиентами происходит по протоколу HTTP - HyperText Transfer Protocol. HTTP - это основной протокол передачи, используемый в Интернет. На сегодняшний день действует спецификация протокола HTTP версии 1.1. HTTP до сих пор не поддерживает сессии и представляет собой простой протокол запросов - ответов, спроектированный для типичного клиент-серверного поведения. Для обеспечения надежности HTTP использует соединения, предоставленные транспортным протоколом TCP/IP. Основная задача HTTP-сервера - это ожидание запросов от клиентов и отправка им ответов. Клиент (обычно веб-браузер) запрашивает ресурс (обычно HTML файл или графический файл). Сервер связывает запрос с файлом или направляет запрос программе, которая генерирует необходимые данные. После этого сервер отсылает ответ обратно клиенту.

Структура данных HTTP

Передача HTTP данных основана на сообщениях. Запрос, поступивший от клиента, также как и ответ сервера, преобразуется в сообщения. Каждое HTTP сообщение состоит из заголовка и тела сообщения (последнее не обязательно). Заголовок и тело HTTP-сообщения разделены пустой строкой.

HTTP-заголовок состоит из 4 частей:

  • запрос/строка статуса (в зависимости от того, запрос это или ответ);
  • главный заголовок;
  • заголовок запроса/ответа;
  • заголовок объекта.

Большинство полей заголовка не являются обязательными. Самый простой запрос требует только строку запроса и (с версии HTTP 1.1) поле главного заголовка "HOST". Самый простой ответ сервера содержит только строку состояния.

Сказанное можно проиллюстрировать примером обращения к информационному ресурсу. В HTTP информационные ресурсы адресуются с помощью URI (Унифицированный идентификатор ресурса) или URL (Унифицированный локатор ресурса). Хотя URI и URL исторически имели различные концепции, сегодня в основном используется URL. Пример URL: http://website-ru.net/basic/cgi-intro.shtml. В этом примере URI имеет значение /basic/cgi-intro.shtml. Результатом обращения к ресурсу http://website-ru.net/txt/basic/cgi-intro.shtml будет следующий запрос:

	GET /txt/basic/cgi-intro.shtml HTTP/1.1
	HOST: website-ru.net

Вот еще два примера полей заголовков:

  • "Content-length" / "Content-type" используются для определения длины и MIME типа тела сообщения. Любой запрос или ответ, обладающий телом, использует эти поля.
  • "Referer" используется клиентским приложением для определения родительского документа, использованного для запроса текущего документа. Эти данные могут быть сохранены на сервере для дальнейшего анализа.

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

HTTP методы

Самой главной директивой HTTP-запроса является метод доступа. Он указывается первым словом в первой строке запроса. В приведенном выше примере это GET. Стандарт HTTP/1.1 определяет следующие методы: GET, POST, OPTIONS, HEAD, TRACE, PUT, DELETE, CONNECT. Наиболее часто используемые методы - это GET и POST.

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

Запросы по методу GET подразделяются на запросы по типам кодирования: isindex и form-urlencoded. Запрос типа isindex - это запрос вида:

	http://domain_name/somthing-cgi/cgi-script?word1+word2+word3 

Главным здесь является список слов после символа "?". Слова перечисляются через символ "+" и для кириллицы в шестнадцатеричные последовательности не кодируются.

Запрос типа form-urlencoded - это запрос вида:

	http://domain_name/somthing-cgi/cgi-script?field=word1&field2=word2 

Данные формы записываются в виде пар "имя_поля=значение", которые разделены символом "&".

Сервер преобразует данные, полученные в запросе по методу GET (то есть последовательность слов после символа "?") в переменную окружения QUERY_STRING. При этом если в значениях полей появляется кириллица или специальные символы, то они заменяются шестнадцатиричным кодом символа, которому предшествует символ "%".

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

Для передачи информации серверу методом GET клиент добавляет ее к URI запроса. Однако это может привести к некоторым проблемам:

  • Длина URI может вызвать ошибку обработки на сервере.
  • Некоторые клиенты могут передавать URI только определенной длины.
  • Большинство клиентов показывают пользователю добавленную к URI информацию.

Метод POST отличается от GET тем, что имеет тело запроса для передачи дополнительных данных серверу. Запросы по методу POST по типу кодирования подразделяются на multipart/form-data и form-urlencoded. На серверной стороне при получении запроса по методу POST данные после символа "?" не будут размещаться в переменной QUERY_STRING, а будут направлены в поток стандартного ввода скрипта, который обрабатывает запрос. Количество символов в потоке стандартного ввода скрипта будет указано в переменной окружения CONTENT_LENGTH, а в переменную окружения CONTENT_TYPE помещается тип кодирования данных, которые считываются из потока стандартного ввода.

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

Хотя метод POST является лучшим способом передачи данных на сервер, некоторые приложения используют для этой цели метод GET, особенно для передачи небольших объемов данных или для возможности добавления закладок на URL.

Все остальные методы используются гораздо реже:

Метод HEAD. Этот метод запрашивает только заголовки ответа сервера. Он может использоваться, например, когда проверяется существование определенного документа на сервере. Ответ выглядит так же, как если бы Вы запросили его методом GET, но только не содержит тело сообщения.

Метод OPTIONS. Используя этот метод, клиент может запросить список методов и опции сервера для определенного ресурса.

Метод TRACE. Метод TRACE схож с командой Ping в TCP/IP. Сообщение этого запроса обязательно содержит в заголовке поле "Max-Forwards". Каждый раз, когда это сообщение проходит через прокси-сервер, значение данного поля уменьшается на единицу. Сервер, который получил это сообщение с нулевым значением, отсылает ответ. Если сообщение получает сервер, которому оно адресовалось, то он отсылает ответ, не обращая внимания на значение поля "Max-Forwards". Используя последовательность таких запросов, клиент может узнать все прокси-сервера, используемые при передаче запрошенного ресурса.

Метод PUT. Используется для передачи серверу файлов. Этот метод схож с командой PUT, используемой в FTP. Применение данного метода несет угрозу безопасности сервера и поэтому он почти никогда не используется.

Метод DELETE. Этот метод удаляет на сервере файл, заданный в URI. Так как данный метод также является угрозой безопасности, то ни один из популярных HTTP серверов не обрабатывают его. Метод DELETE очень схож с командой DELETE в FTP.

Метод CONNECT. Эта команда используется для создания безопасного SSL соединения через прокси-сервер. Прокси-сервер должен открыть безопасное соединение с сервером назначения и передать все данные вне зависимости от их содержания.

Механизм генерации отклика скриптом

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

  • через переменные окружения;
  • через аргументы командной строки;
  • через поток стандартного ввода.

а способ вернуть данные серверу - только один: писать в поток стандартного вывода (STDOUT). При этом скрипт должен формировать HTTP-сообщение.

Сначала выводятся директивы HTTP-заголовка. В минимальном варианте это либо

	Content-type: text/html, 

либо

	Location: http://domain_name/ 

В первом случае определяется тип тела HTTP-сообщения, а во втором осуществляется перенаправление запроса.

После заголовка генерируется отклик в виде тела HTTP-сообщения, которое должно быть отделено от заголовка пустой строкой:

	#!/bin/sh
	echo Content-type: text/plain
	echo
	echo Hello 

В данном случае используется командный интерпретатор sh.

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

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

  • 1хх Информационные - Например: 100 Продолжение (100 Continue).
  • 2хх Успешные - Например: 200 ОК.
  • 3хх Перенаправление - Направляет на другой URL.
  • 4хх Ошибка клиента - Например: 404 Не найдено (404 Not found) или 403 Не доступен (403 Forbidden).
  • 5хх Ошибка сервера - Например: 500 Внутренняя ошибка сервера (500 Internal Server Error).

Как работает CGI

Теперь мы можем дать описание того, как практически работет механизм CGI с точки зрения веб-мастера. Сделать это лучше всего на примере обработки формы. Между прочим, формы появились в HTML одновременно с CGI и последний был разработан как раз для обработки форм.

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

Пользователь видит на странице форму, заполняет поля формы и нажимает экранную кнопку "Отправить". В форме указан метод отправки - GET или POST. Соответственно, данные отправляются на сервер, где они обрабатываются программой (скриптом), указанным в поле METOD формы.

В результате работы скрипта какие-то данные заносятся в базу данных, или еще каким-то образом используются на сервере, а пользователю выдается сообщение о результате обработки.

Более подробные сведения об использовании механизма Common Gateway Interface ищите по приведенным ниже ссылкам. Чаще всего в сети вам будет встречаться так или иначе переделанный материал Б.Храмцова и др.

Полезные ресурсы

Загляните на досуге

Счетчики

Рейтинг@Mail.ru

LiveInternet

Rambler's Top100