Всё о CGI (Common Gateway Interface )

Что такое CGI?

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

Если это программа, то она должна владеть всякий приемлемый для конкретной операционной системы исполняемый формат. Программы разрешено строчить на чем угодно: C/C++, Pascal, Java, Visual также просто Basic, delphi также т.д.

Если это скрипт (сценарий), то на операционной системе, под которой крутиться веб-сервер вынужден существовать соответствующий интерпретатор сценариев: shell, perl, tcl/tk, command.com также т.д.

Главное, дабы средство разарботки CGI программы (скрипта) отвечало следующим потребностям: - позволяют произносить из стандартного потока ввода (stdin) - приобретать значения переменных окружения (environment variables) - заключать в стандартный поток заключения (stdout)

Для чего используется CGI:

  • Работа со справочными системами также базами данных.
  • Создание динамических HTML документов также ресурсов (в том числе счетчики, гостевые книги также т.д.)
  • Удаленное администрирование различных систем.
  • Просто труд с различными программами, поскольку HTML интерфейс достаточно удобен в использовании, прост в изготовлении также приятно выглядит :)

Механизм труда CGI программ

Как уже было сказано, CGI приобретает входные данные со стандартного потока ввода stdin либо из переменных окружения, но выводит результаты своей труда в стандартный поток заключения stdout. Для тех. кто не знает, что это такое: Стандартный поток ввода (stdin) - отсюда программа (скрипт) по-умолчанию приобретает входную информацию. Обычно это клавиатура, но его можно переназначить, также программа (скрипт) станет приобретать входные данные из файла, сокета, выходного потока иной программы.

Переменные окружения (environment variables) - переменные, определенные для системы также сервера, на которой станет выполняться CGI. .

Стандартный поток вывода (stdout) - сюда программа (скрипт) выводит результаты своей работы. Обычно это "монитор", но его разрешено переназначит на файл, сокет, входной поток иной программы, принтер также т.д.

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

Согласно завершительным веяниям по соблюдению безопасности не рекомендуется использование shell для написания CGI скриптов.

1.1 Вызов CGI без параметров

Простейший скрипт, выводящий текущую дату: #!/bin/sh echo Content-type: text/html echo echo "

Today is " date echo "

" В HTML акте ссылка на него описывется вот таким образом <a href="/cgi-bin/examples/today.cgi">

ВАЖНОЕ ЗАМЕЧАНИЕ Основной погрешностью, которую совершают приблизительно все, кто затевает строчить CGI программы либо скрипты, заключается в том, что они забывают вставить указатель на тип выводимого результата - заголовок выводимого документа. Это другая также третья строчки в примере.

echo Content-type: text/html echo где Content-type: - тип выводимого акта (text/html, image/gif, image/jpeg также т.д.).
Пустая строка в заключении выражает о том, что заголовок кончился также далее следует собственно самолично документ.

1.2 Передача параметров CGI скрипту либо программе

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

При использовании GET параметры добавляются к запрашиваемому URL также его можно вызывать таким образом:

http://какой-то_хост/cgi-bin/какой-то_скрипт?параметры что позволяет действовать на такой скрипт ссылки в HTML документах. А на сервере переданные параметры присваиваются переменной QUERY_STRING.

Текст самого скрипта: #!/bin/sh echo Content-type: text/html echo echo "

Вы посылали вот это:

" echo "" set | grep QUERY_STRING echo "

" echo "Environment
" set echo ""</code>и как он вызывался из этого документа: <a href="/cgi-bin/examples/link.cgi?some_parameters"> Образец труда (ткните тут) </a>

Но применение метода GET для передачи параметров, содержащих конфиденциальную информацию недопустимо, т.к. в данном случае вся эта информация передается открыто.

Метод POST позволяет обеспечить конфиденциальность при передаче параметров скрипту. Но он передает параметры на стандартный поток ввода также для этого приходится использовать формы. Сервер никак не шлет скрипту EOF в конце передачи. Вместо этого вам придется использовать пременную окружения CONTENT_LENGTH, дабы определить какой емкость данных вам надобно вычислять из stdin.

Строчим счетчик

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

Эта голова руководства станет скорее полезна тем, кому интересен именно механизм труда счетчиков, поскольку все прилагаемые примеры особыми "наворотами" по элементы настроек, администрения, также т.п. никак не обладают. Более "навороченые", готовые к эксплуатации счетчики ищите на Altavista, Yahooтакже др. поисковых серверах. Либо спрашивайте в соответствующих конференциях новостей (relcom.www.users, relcom.www.support; в фидошных эхах ru.internet.*).

2.1 Типы счетчиков

По механизму труда счетчики условно можно разделить на пара типа:
  1. CGI скрипты работающие как Server Side Include
  2. CGI скрипты никак не использующие Server Side Include
Server Side Include (SSI) - тип HTML комментария , который указывает Web серверу, что в помещении вызова необходимо подставить динамически сгенерированные данные. Основной формат вызова SSI в теле HTML документа выглядит следующим образом:

<!--#command tag="value"...-->

где #command - любая из многочисленных команд понимаемых Web сервером. В данном случае наибольший интерес представляет команда #exec, которая позволяет выполнять программы также подставлять результаты их работы. Анализируемые Web сервером HTML документы называются server-parsed документами.

2.2 Cчетчик посещений работающий как SSI

Алгоритм работы:

  1. Сервер приобретает от браузера запрос на HTML документ.
  2. Сервер просматривает акт на наличие вызова SSI.
  3. Если такие вызовы обнаружены, то на их помещение подставляется результат. В случае команды #exec - результат труда программы, указанной в "value".
  4. Сформированный HTML акт пустился в обратный путь браузеру.

Необходимые настройки сервера (на образце сервера Apache):

  1. В файле srm.conf прописать (если там еще никак не прописано): AddType text/html .shtml AddHandler server-parsed .shtml Эти директивы выражают серверу, что файлы с раширением .shtml являются server-parsed документами.
  2. В файле access.conf на директорию, в каком месте будут лежать server-parsed документы, в Options добавить опцию Includes.
  3. Файлам, содержащим вызовы SSI присвоить расширение .shtml (см. п. 1)
Продемонстрируем работу счетчика на образце скрипта counter, найденного в Интернете на http://www.webtools.org/. Он написан на столь популярном нынче Perl'е.

Вот тут будем вычислять : <!--#exec cgi="/cgi-bin/counter"-->
(нажимайте Reload пока никак не надоест)

Этот счетчик текстовый, т.е. скрипт отдаёт просто текст, какой и показывается. Схожим образом разрешено заключать также картинки. Для этого нужно, чтоб взамен текстовых цифр выводились тэги img src="картинка_с_соответсвующей_цифрой". Пытливый чтец легко догадается, что количество тегов img src... равно числу цифр в значении возвращаемом счетчиком.

Вызов этого счетчика в теле акта осуществляется командой: <!--#exec cgi="/cgi-bin/counter"-->

2.3 Счетчик никак не использующий SSI

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

  • в теле HTML акта указывается: <img src="/cgi-bin/examples/counter.cgi">т.е. запрашиваемая картинка никак не является статической, а динамически генерируется CGI скриптом.
  • сервер, получив запрос на картинку, запускает скрипт, указанный в src тэга img.
  • скрипт, увеличивает значение счетчика на штуку, генерирует картинку со значением счетчика также отдаёт ее браузеру.

Поскольку этот тип счетчиков является самым популярным в Интернете, то алгоритм его труда рассмотрим более подробно.

Скрипт (counter.cgi), какой вызывается в теле HTML документа тэгом img src="...counter.cgi" написан на shell также владеет следующий исходный текст (номера строк добавлены только для упрощения объяснения): 1: #!/bin/sh 2: now=`date -u` 3: echo "Content-type: image/gif;" 4: echo "Expires: $now" 5: echo 6: counter|showdigits

Что действует этот скрипт (построковое описание):
1 - Заголовок самого скрипта. Он указывает на командный интерпретатор, какой станет его выполнять.

2 - Определяем переменную now, которая содержит время запуска скрипта (время создания картинки). Ключик '-u' говорит, что, дата/время создания выводяться в GMT. Зачем это надобно станет описано ниже.

3 - Затеваем формировать заголовок возражения сервера. Указываем тип возвращаемых данных: image/gif

4 - Поскольку это счетчик, то необходимо обеспечить, дабы картика с его показаниями никак не кэшировалась (а то какой он позже этого счетчик:). Для этого указываем, что полученая браузером картинка должна немедля заэкспайриться. Вот тут то мы также используем переменную now, определенную в строке номер 2. Употребление Expires в таком виде соответствует стандарту на HTTP протокол версии 1.1. Но при использовании Expires равным дате создания акта могут начинаться забавные глюки, ежели часы на заказчике отстают от часов сервера на несколько минут. Начинается дилемма - по стандарту положено так, но получается никак не то что надо. Что делать? В предыдущей версии протокола (HTTP 1.0) Expires разрешено было выставлять равным 0, но RFC2068 гласит, что клиенты также кэши работающие по HTTP 1.1 должны поддерживать древний вариация использования Expires (Expires: 0). Так шта, дорогие россияне, решайте сами.

5 - Конец заголовка возражения - возвращаем пустую строку.

6 - Используя две программы (counter также showdigits) генерим саму картинку.

Программы counter также showdigits написаны на Си с использованием библиотеки для труда с GIF файлами - libgd. Без нее программы компилироваться никак не будут. Последнюю версию библиотеки прктически всегда можно получить на http://www.boutell.com/gd/.

Что действуют данные программы:

  • counter - читает из файла counter.rc количество, представляющее из себя предыдущее значение счетчика, добавляет к нему единичку также строчит назад. Если никак не указан маршрут к файлам - картинкам с цифрами также маска этих файлов,то береться дефолтовая, которая определна в теле программы. После этого она вычисленное значение счетчика также маршрута к картинкам выводяться на stdout, чем формируется коммандная строка для showdigits.
  • showdigits - эта программа, собственно, также формирует картинку с текущим показанием счетчика. Для этого используется набор готовых картинок с цифрами (gif формат, все картинки одинакового размера) также полученные на stdin от counter данные. По маршруту, маске также числу беруться нужные картинки также из них собирается один гиф. После чего он отправляется прямиком на ... stdout! А далее сервер перенапрявляет этот поток браузеру также он (браузер) иллюстрирует его как картинку, поскольку в заголовке возражения указано, что это гиф.
Вся сущность тут вот в чем: - Сервер передает браузеру поток данных. - Браузеру полно все равно, в каком месте также как сервер взял передаваемый ему поток данных (статический ли это, либо динамически сгенеренный; обычный файл либо результат жизнедеятельности скрипта), суть, чтоб браузер знал как его правильно интерпретировать. Для этого служит заголовок, какой в данном образце был сгенерирован скриптом counter.cgi, но именно в 3-5 строках (см. выше). Причем, в случае статических файлов сервер самолично генерирует этот заголовок, исходя из собственных настроек, но в случае с cgi это должен делать самолично скрипт.

Server side includes

Ежу понятно, что статические HTML документы - это хорошо, но динамически создаваемые - еще лучше.:) Так вот, в этой голове мы поговорим о динамическом создании документов с использованием Server Side Includes. Разом отметим, что возможность использования SSI - это возможность каждого конкретного сервера. Некоторые сервера никак не поддерживают SSI, но у тех, которые имеют такую возможность, могут разниться форматы также наборы команд. Так что, читайте инструкцию по эксплуатации вашего Web-сервера. Все примеры в этой главе приведены для сервера Apache.

3.1 Что такое SSI

Как уже было сказано впредыдущей главе, Server Side Include (SSI) директива Web-сервера, позволяющая серверу подставлять на помещение вызова какие-либо данные. В HTML акте вызов SSI выглядит как комментарий формата:

<!--#command tag="value"...-->

где #command - любая из SSI директив понимаемых Web сервером, но "value" - ее параметры.

Подставляемые данные могут быть статическими также динамически генерируемыми. Статические данные уже готовые, записанные в виде файлов, фрагменты текста либо HTML. Такие данные удобно применять в случае, в какое время в различных HTML документах помещаться повторяющиеся фрагменты. Динамически генерируемые данные результаты труда каких-либо CGI скриптов либо команд операционной системы, на которой трудится конкретный Web-сервер. Использование этого типа данных предоставляет Web-девелоперу огромные возможности. Но, как гласит дебильная российско-буржуйская реклама, - "Не забывай про Орбит без сахара!". То бишь, ПОМНИ О МЕРАХ ПО СОБЛЮДЕНИЮ БЕЗОПАСНОСТИ ДОСТУПА К ИНФОРМАЦИИ! Неправильное использование SSI может привести к появлению возможности несанкционированного доступа к информации а также, соответственно, к различным тяжким последствиям. .

3.2 Основные SSI директивы

config управляет различными аспектами разбора (parsing) документа. Атрибуты: errmsg сообщение об погрешности, возвращаемое клиенту, ежели при разборе документа произошел какой-либо сбой. sizefmt устанавливает формат заключения размера файла (байты, килобайты, мегабайты). timefmt устанавливает формат заключения даты/времени. echo печатает значение одной из нижеописаных переменных окружения. Атрибуты: var имя печатаемой переменной exec выполняет указанную команду либо CGI скрипт. Атрибуты: cgi указывается (%-кодированый) URL-относительный маршрут к CGI скрипту. Если маршрут никак не начинается с (/), считается, что маршрут указан относительно текущего документа.

CGI скрипту передаются так бла бла значения переменных PATH_INFO и QUERY_STRING оригинального запроса клиента.

cmd сервер выполняет указанную строку, используя командный интерпретатор операционной системы. fsize печатает размер указанного файла с учетом sizefmt. Атрибуты: file указывается маршрут к файлу относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный маршрут к файлу. Если маршрут не начинается с (/), считается, что маршрут указан относительно текущего документа. flastmod печатает дату/время завершительного изменения указанного файла с учетом timefmt. Атрибуты такие бла бла как у команды fsize. include вставляет текст иного акта либо файла в анализируемый документ. Очень полезна при повторяющихся фрагментах в разных документах. Атрибуты: file указывается маршрут к файлу только относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный маршрут к файлу. Если маршрут не начинается с (/), считается, что маршрут указан относительно текущего документа. В Apache включаемые таким образом файлы могут существовать вложенными. printenv печатает перечень всех существующих переменных также их значения. Атрибутов нет. Пример:
<!--#printenv --> set устанавливает значение переменной. Атрибуты: var указывается имя устанавливаемой переменной. value указывается значение устанавливаемой переменной. Пример:
<!--#set var="variable_1" value="some_value_of_variable_1" -->

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

DOCUMENT_NAME - имя файла Описание в теле документа: <!--#echo var="DOCUMENT_NAME" --> Результат использования:<!--#echo var="DOCUMENT_NAME" -->

DOCUMENT_URI - виртуальный маршрут к файлу Описание в теле документа: <!--#echo var="DOCUMENT_URI" --> Результат использования:<!--#echo var="DOCUMENT_URI" -->

QUERY_STRING_UNESCAPED - раскодированя query string, причем все метасимволы shell предваряются "\" Описание в теле документа: <!--#echo var="QUERY_STRING_UNESCAPED" --> Результат использования: (none)

DATE_LOCAL - текущая дата также пора (местное) Описание в теле документа: <!--#echo var="DATE_LOCAL" --> Результат использования:<!--#echo var="DATE_LOCAL" -->

DATE_GMT - текущая дата также пора (GMT) Описание в теле документа: <!--#echo var="DATE_GMT" --> Результат использования:<!--#echo var="DATE_GMT" -->

LAST_MODIFIED - дата также пора завершительного изменения файла Описание в теле документа: <!--#echo var="LAST_MODIFIED" --> Результат использования:<!--#echo var="LAST_MODIFIED" -->

3.4 Настройка сервера

Для того, дабы серевер знал, в каком помещении в акте подставлять данные, он вынужден этот акт проанализировать. Анализируемые сервером документы называются server-parsed документами.

В первую очередь надобно дать осознать серверу, какие документы он должен анализировать. Для этого в файл конигурации (для Apache старых версий также NCSA web-серверов это файл srm.conf, но для новых версий Apache, например 1.3.4 - httpd.conf), нужно добавить следующие параметры: Сервер Apache:

AddType text/html .shtml<br>AddHandler server-parsed .shtml

Сервер NCSA:

AddType text/x-server-parsed-html .shtml Указанные параметры выражают о том, что все файлы с расширением .shtml являются server-parsed, также пред тем как "отдать" этот акт заказчику сервер должен их проанализировать.

Зачем указывать отдельное расширение для server-parsed документов?,- спросит пытливый читатель. Отвечаем. Конечно, ни один человек не препятствует добавить в файл конфигурации строку

AddType text/x-server-parsed-html .html Однако это приведет к тому, что сервер станет исследовать все документы с расширением.html, даже ежели в них нет вызова SSI, загрузка системы увеличиться, но производительность сервера снизится.

Не следует забывать также о том, что безуспешно включать вызов SSI в CGI программы, поскольку их заключение сервером не анализируется.

Для получения более детальной информации по конфигурированию вашего сервера на предмет использования SSI читайте документайию на ваш сервер.

Приложения

Приложение 1. Переменные окружения сервера

Ниже приведен перечень основных переменных окружения сервера с краткими описанием назначения.В данном случае сервер Apache 1.2.5 с модулем PHP/FI-2.0.1. Для других веб-серверов (MS IIS, Netscape, NCSA httpd, также т.д.) переменные могут отличаться.

REMOTE_HOST - имя хоста приконнектившегося к серверу. В случае работы через прокси - имя прокси.
Пример: REMOTE_HOST=lom.pvrr.ru

REMOTE_ADDR - IP адрес хоста приконнектившегося к серверу. В случае работы чрез прокси - IP адрес прокси.
Пример: REMOTE_ADDR=194.87.186.11

REMOTE_PORT - номер порта клиента.
Пример: REMOTE_PORT=3381

HTTP_USER_AGENT - имя/номер версии/и т.д. заказчика (браузера). Использование этой переменной иной раз приводит в неистовство отдельных пользователей Интернет.:) Но на самом занятии весьма полезная вещь. Например для автоопределения русских кодировок.
Пример:HTTP_USER_AGENT=Mozilla/4.07 [en] (X11; I; FreeBSD 2.2.6-RELEASE i386)

HTTP_ACCEPT - типы данных, помимо text/html, воспринимаемые клиентом (браузером)
Пример: HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

HTTP_ACCEPT_CHARSET - какие чарсеты понимает заказчик (браузер).
Пример: HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8

HTTP_ACCEPT_LANGUAGE - какие языки воспринимвает заказчик (браузер).
Пример: HTTP_ACCEPT_LANGUAGE=nl,nl-BE,ru

* * *

SERVER_NAME - имя сервера соответствующее записи IN A в DNS, или значение переменной ServerName (или похожей) в конфиге сервера.
Пример: SERVER_NAME=arche.pvrr.ru

HTTP_HOST - имя сервера либо виртуального хоста, к которому обращается клиент. Значение HTTP_HOST может существовать равным значению SERVER_NAME.
Пример: HTTP_HOST=www.pvrr.ru

SERVER_SOFTWARE - какое ПО используется в качестве сервера.
Пример: SERVER_SOFTWARE=Apache/1.2.5 PHP/FI-2.0.1

DOCUMENT_ROOT - маршрут к "корню" веб-сервера от "корня" файловой системы копьютера, на котором он работает.
Пример: DOCUMENT_ROOT=/usr/local/www/html

HTTP_CONNECTION - тип соединения.
Пример: HTTP_CONNECTION=keep-alive

SERVER_PROTOCOL - протокол, используемый для обмена данными с конкретным клиентом.
Пример: SERVER_PROTOCOL=HTTP/1.0

REQUEST_URI - имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. При обращении к корню сервера либо каталогу этой переменной присваивается имя каталога либо "/" в случае корня сервера.
Пример: REQUEST_URI=/cgi-bin/tralala/script.cgi

DOCUMENT_URI - имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. Обычно инициализируется при вызове SSI. В отличие от REQUEST_URI эта переменная, в случае обращения к каталогу либо корню сервера получает значение содержащее также имя файла, являющегося Directory Index'ом этого каталога.
Пример: DOCUMENT_URI=/tralala/index.shtml

HTTP_REFERER - наполненный URL документа, по ссылке с которого вы попали на этот сервер. Данную переменную разрешено использовать при написании счетчиков.
Пример: HTTP_REFERER=http://lom.pvrr.ru/java/cgi/cgi_1.html

GATEWAY_INTERFACE - название/версия интерфейса, чрез какой сервер работает со скриптом.
Пример: GATEWAY_INTERFACE=CGI/1.1

SCRIPT_FILENAME - имя скрипта, содержащее наполненный маршрут от "корня" файловой системы.
Пример:SCRIPT_FILENAME=/usr/local/www/cgi-bin/tralala/script.cgi

SCRIPT_NAME- имя скрипта, содержащее маршрут от "корня" веб-сервера.
Пример: SCRIPT_NAME=/cgi-bin/tralala/script.cgi

REQUEST_METHOD - метод используемый заказчиком для передачи данных серверу. Бывают GET, HEAD, POST, PUT.
Пример: REQUEST_METHOD=GET

QUERY_STRING - этой переменной значение присваивается при передаче данных серверу методом GET
Пример: QUERY_STRING=button=on

CONTENT_LENGTH - этой переменной присваивается значение, равное количеству байт, переданных браузером серверу при использовании метода POST.
Пример: CONTENT_LENGTH=9

REMOTE_USER - имя пользователя. Передается только если аутентифицируется доступ к CGI скрипту.

PATH_INFO - дополнительная информация о маршруту, которую передал клиент. То кушать скрипт может приобретать некоторые параметры, содержащие информауцию о некотором "маршруте" к некоторым данным (например к файлу конфигурации, необходимому для отделки запроса отименно этого клиента). Этот маршрут "виртуальный" - т.е от "корня веб-сервера". Остальные данные разрешено передавать как обычно - методом GET или POST.
Пример: PATH_INFO=/some/path

PATH_TRANSLATED - то бла бла , что также PATH_INFO, только маршрут физический - "от корня файловой системы"

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

SERVER_ADMIN - e-mail правителя веб-сервера.
Пример: SERVER_ADMIN=webmaster@www.pvrr.ru

SERVER_PORT - порт, какой "слушает" веб-сервер.
Пример: SERVER_PORT=80

* * *

HTTP_X_FORWARDED_FOR - в случае труда чрез прокси - IP адрес клиента, работаеющего чрез прокси.
Пример: HTTP_X_FORWARDED_FOR=194.87.186.11

HTTP_VIA - имя, номер порта, разновидность ПО прокси-сервера.
Пример: HTTP_VIA=1.0 proxy1.pvrr.ru:8080 (Squid/2.1.PATCH1)

HTTP_CACHE_CONTROL - что-то связанное с возрастом акта в кэше прокси сервера:) Лгать никак не буду - никак не знаю:)
Пример: HTTP_CACHE_CONTROL=max-age=259200