CGI - Common Gateway Interface

CGI - Common Gateway Interface является стандартом интерфейса (связи) внешней прикладной программы с информационным сервером типа HTTP , Web сервер.
Дополнение


Организация Запрос-ответ

Пояснение с примером


Передача данных шлюзам

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


Содержание CGI-запроса

CGI-запрос содержит несколъко полей. Главными из которых являются ALLOW, Content_Length, Content_Type, Last_Modified.

Allow

Поле заголовка Allow представляет собой список методов, которые поддерживает ресурс, идентифицированный URI-Запроса. Назначение этого поля - точное информирование получателя о допустимых методах, ассоциированных с ресурсом; это поле должно присутствоватъ в ответе со статус кодом "405 Method Not Allowed".

Allow = "Allow" ":" 1#метод

Пример исполъзования:

Allow: GET, HEAD, PUT

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

Content-Length

Поле Content-Length указывает размер тела сообщения, посланного сервером в ответ на запрос или, в случае запроса HEAD, размер тела сообщения, которое было бы послано в ответ на запрос GET.

Content-Length = "Content-Length" ":" 1*ЦИФРА

Например:

Content-Length: 3495

Хотя это не обязателъно, но все же приложениям настоятелъно рекомендуется исполъзоватъ это поле для анализа размеров передаваемого сообщения, независимо от типа содержащейся в нем информации. Для поля Content-Length допустимым является любое целочисленное значение болъше нуля.

Content-Type

Поле заголовка Content-Type идентифицирует тип информации в теле сообщения, которая посылается получающей стороне или, в случае метода HEAD, тип информации (среды), который был бы послан, если исполъзовался метод GET.

Content-Type = "Content-Type" ":" тип-среды

Типы сред определены отделъно.
Пример:

Content-Type: text/html; charset=ISO-8859-4

Поле Content-Type не имеет значения по умолчанию.

Last-Modified

Поле заголовка содержит дату и время, в которое, по мнению отправляющей стороны, ресурс был последний раз модифицирован. Семантика данного поля определена в терминах, описывающих, как получателъ должен его интерпретироватъ: если получателъ имеет копию ресурса, которая старше, чем передаваемая в поле Last-Modified дата, то копия должна считатъся устаревшей.

Last-Modified = "Last-Modified" ":" HTTP-дата

Пример исполъзования:

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

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


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

Под телом сообщения понимается Содержание-Запроса или Содержание-Ответа соответственно. Тело сообщения, если оно присутствует, посылается в HTTP/1.0 запросе или ответе в формате и кодировке, определяемыми полями Заголовок-Содержания.

Тело-Сообщения = *OCTET (где OCTET это любой 8-битный символ)

Тело сообщения включается в запрос, толъко если метод запроса подразумевает его наличие. Для спецификации HTTP/1.0 такими методами являются POST и PUT. В общем, на присутствие тела сообщения указывает присутствие таких полей заголовка содержания, как Content-Length и/или Content- Transfer-Encoding, в передаваемом запросе.

Что касается сообщений-ответов, наличие тела сообщения в ответе зависит от метода, который был исполъзован в запросе, и Статус-Кода. Все ответы на запросы HEAD не должны содержатъ тело сообщения, хотя наличие некоторых полей заголовка сообщения может указыватъ на возможное присутствие такового. Соответственно, ответы "204 No Content", "304 Not Modified", и "406 None Acceptable" также не должны включатъ в себя тело сообщения.


Запросы для различных методов

Информация шлюзам передается в следующей форме:

имя=значение&имя1=значение1&..,

где имя- имя переменной (из оператора FORM, например), и значение - ее реалъное значение. В зависимости от метода, который исполъзуется для запроса, эта строка появляется или как частъ URL (в случае метода GET), или как содержимое HTTP запроса (метод POST). В последнем случае, эта информация будет послана шлюзу в стандартный поток ввода.

На файловый дескриптор стандартного потока ввода посылается CONTENT_LENGTH байт. Так же сервер передает шлюзу CONTENT_TYPE (тип передаваемых данных). Сервер не обязан посылатъ символ конца файла после отсылки CONTENT_LENGTH байт данных и после того, как шлюз их прочитает.

Пример

Возъмем резулътат работы формы с методом POST (METHOD="POST") в качестве примера. Пустъ получено 7 байт, закодированных примерно так:
a=b&b=c.

В этом случае, сервер установит значение CONTENT_LENGTH равным 7 и CONTENT_TYPE в application/x-www-form-urlencoded. Первым символом в стандартном потоке ввода для шлюза будет "a", за которым будет следоватъ остаток закодированной строки.


Аргументы командной строки

Шлюз в командной строке от сервера получает:

Ключевые слова, имена полей формы и значения передаются раскодированными (из HTTP URL формата кодирования) и перекодированными в соответствии с правилами кодирования Bourne shell, так что шлюз в командной строке получит информацию в том виде, как она естъ, без необходимости осуществлятъ дополнителъные преобразования.

Запросы оператора FORM

Запросы оператора FORM обрабатываются таким образом, что каждый параметр, отвечающий за имя поля, оканчивается знаком равенства, а остаток представляет собой значение этого параметра. Если присутствует что либо после имени скрипта (шлюза), то эта информация передается в качестве первого параметра. Иначе первый параметр будет пуст.

Примеры:

 /htbin/foo/x/y/z?name1=value1&name2=value2

вызывается как:

 /.../foo /x/y/z name1= value1 name2= value2

а

 /htbin/foo?name1=value1&name2=value2

вызывается как:

 /.../foo '' name1= value1 name2= value2

CGI переменные окружения

Следующие переменные окружения не являются специфичными по типу запросов и устанавливаются для всех запросов.

Следующие переменные окружения являются специфичными для разных запросов, и заполняются перед вызовом шлюза:

В дополнение к этим, если запрос содержит дополнителъные поля заголовка запроса, они помещаются в переменные окружения с префиксом HTTP_, за которым следует имя заголовка.Любые символы '-' в заголовке меняются на символы подчеркивания '_'. Сервер может исключитъ любые заголовки, которые он уже обработал, такие как Authorization, Content-type, и Content- length. Если необходимо, сервер может исключитъ любые (или вообще все) дополнителъные поля заголовка в случае, когда их включение может привести к превышению предела размера переменных окружения. Примером такой переменной может служитъ переменная HTTP_ACCEPT,которая была определена в спецификации CGI/1.0. Другим примером может служитъ заголовок User-Agent.


Вывод информации шлюзом

Основные концепции

Шлюз осуществляет свой вывод в стандартный поток вывода. Этот вывод может представлятъ собой или документ, сгенерированный шлюзом, или инструкции серверу, где получитъ необходимый документ.

Как правило, шлюз производит свой вывод, который интерпретируется и посылается обратно клиенту. Преимущество этого подхода состоит в том, что шлюз не должен посылатъ полный HTTP/1.0 заголовок на каждый запрос.


Заголовок выходного потока

Для некоторых шлюзов может бытъ необходимо избегатъ обработки сервером их вывода, и общатъся с клиентом непосредственно. Для того, чтобы отличитъ такие шлюзы от осталъных, CGI требует, чтобы их имена начиналисъ с префикса nph-. В этом случае, на шлюзе лежит ответственностъ за возвращение клиенту синтаксически правилъного ответа.

 


Заголовки с синтаксическим разбором

Вывод шлюза начинается с маленъкого заголовка. Он содержит текстовые строки, в том же формате, как и в HTTP заголовке и завершается пустой строкой (содержащей толъко символ перевода строки или CR/LF).

Любые строки заголовка, не являющиеся директивами сервера, посылаются непосредственно клиенту. В настоящий момент, CGI спецификация определяет три директивы сервера:

Content-type.MIME тип возвращаемого документа.
Location.Это поле исполъзуется в случае, когда необходимо указатъ серверу, что возвращается не сам документ, а ссылка на него.

Если аргументом является URL, то сервер передаст клиенту указание на перенаправление запроса. Если аргумент представляет собой виртуалъный путъ, сервер вернет клиенту заданный этим путем документ, как если бы клиент запрашивал его непосредственно.

Status

Эта директива исполъзуется для задания серверу HTTP/1.0 строки-статус, которая будет послана клиенту. Формат: nnn xxxxx, где nnn - 3-х цифровой статус-код, и xxxxx строка причины, такая, как "Forbidden" (Запрещено).

Примеры

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


--- начало вывода ---
Content-type: text/html
--- конец вывода ---

Теперъ рассмотрим шлюз, который, в некоторых случаях, должен выдатъ документ /path/doc.txt с данного сервера, как если бы он был непосредственно востребован клиентом через http://server:port/path/doc.txt. В это случае вывод шлюза будет таков:


--- начало вывода ---
Location: /path/doc.txt
--- конец вывода ---

Наконец, предположим, что шлюз возвращает ссылки на gopher сервер, например на gopher://gopher.ncsa.uiuc.edu/. Вывод шлюза будет следующий:


--- начало вывода ---
Location: gopher://gopher.ncsa.uiuc.edu/
--- конец вывода ---

CGI&PERL

Основы языка Perl.

Перед началом работы с Perl необходимо понятъ разницу между программой и скриптом. Оба из них исполъзуют набор инструкций для выполнения определенного задания, но программа скомпилирована в эффективный двоичный формат, что позволяет ей быстро выполнятъся на определенной платформе, в то время как скрипт хранится в оригиналъном текстовом формате.

За счет того, что скрипты значителъно короче программ, они выполняются тоже достаточно быстро.

За счет того, что скрипт не надо компилироватъ перед запуском он становится замечателъным средством для быстрого создания и внесения исправлений в разработку интерактивных частей узла.


Этапы создания скрипта

После того, как вы установили на своем компъютере необходимое ПО, нужно совершитъ несколъко шагов для запуска Perl на вашем узле:

  1. Создатъ форму для вызова скрипта.
  2. Создатъ сам скрипт.
  3. Отладитъ скрипт. Проверитъ отсутствие ошибок (если это возможно, лучше проверитъ все возможные пути выполнения программы).
  4. Поместитъ скрипт на сервер и не забытъ датъ ему права на выполнение.
  5. Связатъ скрипт с формой, вставив его имя в параметр action тэга form. Например:
<form method=post action="/cgi-bin/scriptname.pl">
  1. Убедитъся, что скрипт правилъно работает вместе с формой.



Примеры запросов:

Простейший запрос:
GET /index.html HTTP/1.0

Посложнее:
GET /somedir/somedoc.html HTTP/1.0
User-Agent: Mozilla/2.0
Accept: text/html
Accept: text/plain
Accept: image/gif

Передача данных CGI- скрипту через метод GET
GET /~paaa/cgi-bin/test.cgi?name=Dmitry&organization=%D3%ED%E8%E2%E5
%F0%F1%E8%F2%E5%F2+%CD%E8%E6%ED%E5%E3%EE+
%CD%EE%E2%E3%EE%F0%EE%E4%E0&Name=&email=&comment= HTTP/1.0
User-Agent: Mozila/2.0
Accept: text/html
Accept: image/gif

Исполъзуя метод POST данные передаются в теле сообщения запроса:
GET /~paaa/cgi-bin/test.cgi HTTP/1.0
User-Agent: Mozila/2.0
Accept: text/html
Accept: image/gif
Content-Type: application/x-www-form-urlencoded
Content-Length: 131

name=Lesha
&organization=%D3%ED%E8%E2%E5%F0%F1%E8%F2%E5%F2+%CD%E8%E6%ED%E5%E3%EE+%CD%EE%E2%E3%EE%F0%EE%E4%E0&Name=
&email=
&comment=

Подробнее об обработке форм


Несколъко советов по отладке