CGI-logo CGI - Общий Интерфейс Шлюзов



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

Обычно гипертекстовые документы, написанные на языке HTML, представляемые на WWW сервере, содержат статические данные. С помощью CGI можно создавать CGI-программы, называемые шлюзами или скриптами (CGI Script), которые во взаимодействии с такими прикладными системами, как система управления базой данных, электронная таблица, деловая графика и др., смогут выдать на экран пользователя динамическую информацию.

Программа-шлюз запускается WWW сервером в реальном масштабе времени. WWW сервер обеспечивает передачу запроса пользователя шлюзу, а она в свою очередь, используя средства прикладной системы, возвращает результат обработки запроса на экран пользователя. Программа-шлюз (CGI Script) может быть написана на языках:

Как выполняемый модуль, такая программа как правило помещается в поддиректорию с именем cgi-bin WWW сервера. В принципе она может быть помещена в любую другую директорию, в которой разрешено выполнение исполняемых модулей.

Оригинал описания CGI -- интерфейса между CGI-Script и WWW сервером находится по адресу http://hoohoo.ncsa.uiuc.edu/cgi/.


Передача данных

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

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

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

имя=значение&имя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.
Первым символом в стандартном потоке ввода для программы CGI Script будет "a", за которым будет следовать остаток закодированной строки.

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

Программа CGI Script в командной строке от сервера получает:

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

Запросы команды FORM

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

Примеры:

  1.  /test-cgi.sh/foo/x/y/z?name1=value1&name2=value2

    вызывается как:
    /.../foo /x/y/z name1=value1 name2=value2

    http://www.ict.nsc.ru/cgi-bin/test-cgi.sh/foo/x/y/z?name1=value1&name2=value2

  2.  /test-cgi.sh/foo?name1=value1&name2=value2

    вызывается как:
     /.../foo  name1=value1 name2=value2

    http://www.ict.nsc.ru/cgi-bin/test-cgi.sh/foo?name1=value1&name2=value2

Cм. также другие примеры обращениия к CGI Script программе).

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

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

SERVER_SOFTWARE
Название и версия информационного сервера, который отвечает на запрос (и запускает программу CGI Script). Формат: имя/версия.
SERVER_NAME
Имя хоста, на котором запущен WWW сервер, DNS имя, или IP адрес в том виде, в котором он представлен в URL.
GATEWAY_INTERFACE
Версия CGI спецификации на тот момент, когда компилировался сервер. Формат: CGI/версия.

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

SERVER_PROTOCOL
Имя и версия информационного протокола, в котором пришел запрос. Формат: протокол/версия.
SERVER_PORT
Номер порта, на который был послан запрос.
REQUEST_METHOD
Метод, который был использован для запроса. Для HTTP, это методы "GET", "HEAD", "POST", и т.д.
PATH_INFO
Дополнительная информация о пути, которую передал клиент. Другими словами, доступ к программе может быть осуществлен по виртуальному пути, за которым следует некоторая дополнительная информация. Эта информация передается в PATH_INFO.
PATH_TRANSLATED
Сервер передает преобразованную версию PATH_INFO, которая включает в себя путь, преобразованный из виртуального в физический.
SCRIPT_NAME
Виртуальный путь к программе, который должен выполняться, используемый для получения URL.
QUERY_STRING
Информация, следующая за ? в URL, к которому относится данная программа. Это информация представляет собой строку запроса. Она не должна быть декодирована никоим образом. Вне зависимости от командной строки эта переменная всегда должна быть установлена при наличии такой информации.
REMOTE_HOST
Имя хоста, производящего запрос. Если сервер не имеет такой информации, он должен установить REMOTE_ADDR, а это поле оставить не установленным.
REMOTE_ADDR
IP адрес хоста, производящего запрос.
AUTH_TYPE
Если сервер поддерживает идентификацию пользователя, и программы является защищенной от постороннего доступа, этот специфичный для протокола метод идентификации используется для проверки пользователя.
REMOTE_USER
Используется в ситуациях, аналогичных предыдущему случаю, для хранения имени пользователя.
REMOTE_IDENT
Если HTTP сервер поддерживает идентификацию пользователя согласно RFC 931, то эта переменная будет содержать имя пользователя, полученное от сервера.
CONTENT_TYPE
Для запросов, которые содержат дополнительную добавочную информацию, такие как HTTP POST и PUT, здесь содержится тип данных этой информации.
CONTENT_LENGTH
Длина данных, которую передает клиент.

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

HTTP_ACCEPT
Список MIME типов, которые клиент может обработать, как задано в HTTP заголовках. Другие протоколы должны получить эту информацию из других мест (если она им необходима). Каждый тип в этом списке должен быть отделен запятой согласно HTTP спецификации. Формат: тип/подтип, тип/подтип.
HTTP_USER_AGENT
Просмотрщик, который использует клиент для посылки запроса. Общий формат: программа/версия библиотека/версия.
Кроме этоих переменных окружения CGI программы взимодействия сервера с клиентом могут использовать свои переменные окружения (см., например, переменные окружения CGI программы ErrorCGI обработки ошибок на сервере.

Вывод информации программой CGI Script

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

Программа CGI Script осуществляет свой вывод на стандартный вывод системы. Этот вывод может представлять собой или документ, сгенерированный программой, или инструкции серверу, где получить необходимый документ.

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

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

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

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

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

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

Content-type
MIME тип возвращаемого документа.

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

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

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

Примеры

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

    --- начало вывода ---
    Content-type: text/html
    
    ---    вывод     ---
    --- конец вывода ---
    
  2. Рассмотрим программу, которая, в некоторых случаях, должна выдать документ /path/doc.txt с сервера, как бы он был непосредственно востребован клиентом через гиперссылку
    <A HREF="http://server:port/path/doc.txt">.
    В этом случае вывод программы будет следующим:
    --- начало вывода ---
    Location: /path/doc.txt
    
    --- конец вывода ---
    
  3. Предположим, что программа возвращает ссылки на gopher сервер, например:
    <A HREF="gopher://gopher.ncsa.uiuc.edu/">.
    Вывод программы будет следующим:
    --- начало вывода ---
    Location: gopher://gopher.ncsa.uiuc.edu/
    
    --- конец вывода ---
    

Non-parsed headers

Рассмотрим CGI программу, которая общается с клиентом непосредственно. Как уже отмечалось, ее имя должно начинаться с префикса nph- и она должна возвращать клиенту допустимый HTTP заголовок. В этом случае, если доступ к шлюзу был осуществлен со значением SERVER_PROTOCOL равным HTTP/1.0, его вывод должен удовлетворять HTTP/1.0:

--- начало вывода ---
HTTP/1.0 200 OK
Server: NCSA/1.0a6
Content-type: text/plain

--- конец вывода ---

Пример полного задания Заголовка протокола HTTP/1.0:

--- начало вывода ---
HTTP/1.0 200 OK
Date: Tuesday, 26-Dec-95 15:17:10 GMT
Server: NCSA/1.3
MIME-version: 1.0
Content-type: text/html
Last-modified: Tuesday, 24-Dec-95 15:15:41 GMT
Content-length: 3132

--- Здесь находится документ, подготовленный для клиента ---
--- конец вывода ---
Замечание: в качесве значений типа протокола и программного обеспечения сервера можно подставить соответствующие значения переменных окружения:
$SERVER_PROTOCOL
$SERVER_SOFTWARE

Небольшой совет

Рекомендуется всегда ставить атрибут Last-Modified в Заголовок-Содержание выдачи программы CGI Script. Документ без такого указателя не сохраняется в локальном кэше просмотрщика, и постоянно считывется по сети при просмотре.

Пример

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

В качестве примера использавния CGI см. Perl Scrint обработки ошибок сервера, с узла NCSA.

Примечание! Материал подготовлен на основе документа "CGI Specification at NCSA"


Федотов А.М. Введение в Internet
Created 03.02.97.
Last updated Monday, 15-Nov-1999 21:45:09 NOVT
© 1997, Anatolii M.Fedotov