Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS в 21 локации

От 104 рублей в месяц

Безлимитный трафик. Защита от ДДоС.

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

3.5.7. Common Gateway Interface - средство расширения возможностей технологии World Wide Web

Спецификация CGI была разработана в Центре Суперкомпьютерных Приложений Унив-ерситета штата Иллинойс (NCSA). Работы над ней велись параллельно с Mosaic. С точки зрения общей архитектуры программного обеспечения World Wide Web, CGI определила все дальнейшее развитие системных средств. До появления этой спецификации все новые возможности реализовывались в виде модулей, включенных в библиотеку общих кодов ЦЕРН. Разработчики серверов должны были использовать эти коды для реализации программ или заменять их своими собственными аналогами. Это означало, что после компиляции сервера добавить в него новые возможности будет невозможно. CGI в корне изменила эту практику.

Главное назначение Common Gateway Interface - обеспечение единообразного потока данных между сервером и прикладной программой, которая запускается из-под сервера. CGI определяет протокол обмена данными между сервером и программой. Для тех, кто знаком с протоколом HTTP, может показаться, что CGI - это просто подмножество этого протокола. Однако это не так. Во-первых, CGI определяет порядок взаимодействия сервера с прикладной программой, в котором сервер выступает инициирующей стороной, во-вторых, CGI определяет механизм реального обмена данными и управляющими командами в этом взаимодействии, что не определено в HTTP. Естественно, что такие понятия, как метод доступа, переменные заголовка, MIME, типы данных, заимствованы из HTTP и делают спецификацию прозрачной для тех, кто знаком с самим протоколом.

При описании различных программ, которые вызываются сервером HTTP и реализованы в стандарте CGI, используют следующую терминологию:

CGI-скрипт - программа, написанная в соответствии со спецификацией Common Gateway Interface. CGI-скрипты могут быть написаны на любом языке программирования (C, C++, PASCAL, FORTRAN и т.п.) или командном языке (shell, cshell, командный язык MS-DOS, Perl и т.п.). Скрипт может быть написан даже на языке редактора EMAC в системах Unix.

Шлюз - это CGI-скрипт, который используется для обмена данными с другими информационными ресурсами Internet или приложениями-демонами. Обычная CGI-программа запускается сервером HTTP для выполнения некоторой работы, возвращает результаты серверу и завершает свое выполнение. Шлюз выполняется точно также, только, фактически, он инициирует взаимодействие в качестве клиента с третьей программой. Если эта третья программа является сервисом Internet, например, сервер Gopher, то шлюз становится клиентом Gopher, который посылает запрос по порту Gopher, а после получения ответа пересылает его серверу HTTP.

Аналогично происходит взаимодействие с серверами распределенных баз данных, например, Oracle.

3.5.7.1. Механизмы обмена данными

Собственно спецификация CGI описывает четыре набора механизмов обмена данными:

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

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

К общим переменным окружения относятся:

  • SERVER_SOFTWARE - определяет имя и версию сервера.
  • SERVER_NAME - определяет доменное имя сервера.
  • GATEWAY_INTERFACE - определяет версию интерфейса.

К запрос-ориентированным относятся:

  • SERVER_PROTOCOL - протокол сервера. Вообще говоря, CGI разрабатывалась не только для применения в World Wide Web с протоколом HTTP, но и для других протоколов также, но широкое применение получила только в WWW.
  • SERVER_PORT - определяет порт TCP, по которому осуществляется взаимодействие. По умолчанию для работы по HTTP используется 80 порт, но он может быть и переназначен при конфигурировании сервера.
  • REQUEST_METHOD - определяет метод доступа к информационному ресурсу. Это важнейшая переменная в CGI. Разные методы доступа используют различные механизмы передачи данных. Данная переменная может принимать значения GET, POST, HEAD и т. п.
  • PATH_INFO - передает программе путь, часть спецификации URL, в том виде, в котором она указана в клиентом. Реально это означает, что передается путь (адрес скрипта) в виде, указанном в HTML-документе.
  • PATH_TRANSLATED - то же самое, что и PATH_INFO, но только после подстановки сервером определенных в его конфигурации вставок. Дело в том, что при конфигурировании сервера некоторым элементам (ветвям) дерева файловой системы можно назначить синонимы. Типичным примером такого сорта является назначение типа:
    cgi-bin ------------> /usr/local/etc/httpd/cgi-bin
    

    В данном случае справа указано стандартное место CGI скриптов для сервера NCSA, а слева - его синоним. При получении скриптом test управления, в переменной окружения PATH_INFO будет значение:

    "/cgi-bin/test", а в PATH_TRANSLATED -
    "/usr/local/etc/httpd/cgi-bin/test".
    
  • SCRIPT_NAME - определяет адрес скрипта так, как он указан клиентом. Если не указаны параметры, то значение этой переменной будут совпадать с PATH_INFO, но если переменные указаны, то все, что следует за знаком "?" будет отброшено.
    PATH_INFO ----------> "/cgi-bin/search?nuclear+isotop"
    SCRIPT+NAME --------> "/cgi-bin/search"
    
  • QUERY_STRING - переменная определяет содержание запроса к скрипту. Чрезвычайно важна при использовании метода доступа GET. Возвращаясь к примеру с адресами скрипта укажем, что в QUERY_STRING помещается все, что записано после символа "?".
    QUERY_STRING -------> "nuclear+isotop"
    

    При этом никакого преобразования строки запроса сервером не производится. Все манипулирования с содержанием QUERY_STRING возложены на скрипт.

Следующий набор переменных связан с идентификацией пользователя и его машины:

  • REMOTE_HOST - доменный адрес машины, с которой осуществляется запрос.
  • REMOTE_ADDR - IP-адрес запрашивающей машины.
  • AUTH_TYPE - тип идентификации пользователя. Используется в случае если скрипт защищен от несанкционированного использования.
  • REMOTE_USER - используется для идентификации пользователя.
  • REMOTE_IDENT - данная переменная порождается сервером, если он поддерживает идентификацию пользователя по протоколу RFC-931. Рекомендовано использование этой переменной для первоначального использования скрипта.

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

  • CONTENT_TYPE - определяет MIME-тип данных, передаваемых скрипту. Используя эту переменную можно одним скриптом обрабатывать различные форматы данных.
  • CONTENT_LENGTH - определяет размер данных в байтах, которые передаются скрипту. Данная переменная чрезвычайно важна при обмене данными по методу POST, т.к. нет другого способа определить размер данных, которые надо прочитать со стандартного ввода.

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

Опции командной строки. Командная строка используется только при запросах типа ISIN-DEX. При HTML FORMS или любых других запросах неопределенного типа командная строка не используется. Если сервер определил, что к скрипту обращаются через ISINDEX-документ, то поисковый критерий выделяется из URL и преобразуется в параметры командной строки. При этом знаком разделения параметров является символ "+". Тип запроса определяется по наличию или отсутствию символа "=" в запросе. Если этот символ есть, то запрос не является запросом ISINDEX, если символа нет, то запрос принадлежит к типу ISIN-DEX. Параметры, выделенные из запроса, помещаются в массив параметров командной строки argv. При этом после из выделения происходит преобразование всех шестнадцатеричных символов в их ASCII-коды. Если число параметров превышает ограничения, установленные в командном языке, например в shell, то формирования командной строки не происходит и данные передаются только через QUERY_STRING. Вообще говоря, следует заранее подумать об объеме данных, передаваемом скрипту и выбрать соответствующий метод доступа. Размер переменных окружения тоже ограничен, и если необходимо передавать много данных, то лучше сразу выбрать метод POST, т.е. передачу данных через стандартный ввод.

Формат стандартного ввода. Стандартный ввод используется при передаче данных в скрипт по методу POST. Объем передаваемых данных задается переменной окружения CONTENT_LENGTH, а тип данных - переменной CONTENT_TYPE. Если из HTML-формы надо передать запрос типа: a=b&b=c, то CONTENT_LENGTH=7, CONTENT_TYPE=application/x-www-form-urlencoded, а первым символом в стандартном вводе будет символ "а". Следует всегда помнить, что конец файла сервером в скрипт не передается, а поэтому завершать чтение следует по числу прочитанных символов. Позже мы разберем примеры скриптов и обсудим особенности их реализации в разных операционных системах.

Формат стандартного вывода. Стандартный вывод используется скриптом для возврата данных серверу. При этом вывод состоит из заголовка и собственно данных. Результат работы скрипта может передаваться клиенту без каких-либо преобразований со стороны сервера, если скрипт обеспечивает построение полного HTTP-заголовка, в противном случае сервер заголовок модифицирует в соответствии со спецификацией HTTP. Заголовок сообщения должен отделяться от тела сообщения пустой строкой. Обычно в скриптах указывают только три поля HTTP-заголовка:

Content-type, Location, Status.

Content-type указывается в том случае, когда скрипт сам генерирует документ "на лету" и возвращает его клиенту. В этом случае реального документа в файловой системе сервера не остается. При использовании такого сорта скриптов следует учитывать, что не все серверы и клиенты отрабатывают так, как представляется разработчику скрипта. Так, при указании Content-type: text/html, некоторые клиенты не реализуют сканирования полученного текста на предмет наличия в нем встроенной графики. Обычно в Content-type указывают текстовые типы text/plain и text/html.

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

3.5.7.2. Практика применения скриптов CGI

Применение скриптов широко практикуется в WWW. При их помощи, например, реализованы стеки графических гипертекстовых ссылок, встраивание даты в текст документов, встраивание ответов службы finger, доступ к базам данных и многое другое. Мы рассмотрим простейшие скрипты для распечатки параметров, передаваемых сервером, скрипты по обращению к shell, С скрипты, скрипты доступа к системе управления базами данных ingres и скрипт imagemap.

Простейшие скрипты и преобразование информации. Обсуждение начнем со скриптов, написанных на командном языке SHELL. Самый простой из них будет выглядеть как:

#!/bin/sh
echo Content-type: text/plain
echo
echo This is the result of script execution.
#The end of script

Первая строка определяет, что в качестве интерпретатора скрипта будет использован shell, вторая строка открывает заголовок сообщения, передаваемого скриптом серверу, и определяет тип передаваемой информации как обычный текст. Третья строка отделяет тело сообщения от его заголовка. В теле сообщения передается фраза из четвертой строки. Именно она и будет отображаться программой-интерфейсом пользователя.

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

#!/bin/sh
echo Content-type: text/plain
echo
echo $REQUEST_METHOD
echo $QUERY_STRING
echo $CONTENT_TYPE
echo $CONTENT_LENGTH
#The end of script.

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

Пользователю можно вернуть не только значения переменных окружения, но и результаты выполнения команд.

#!/bin/sh
echo Content-type: text/plain
echo
finger paul@polyn.kiae.su
#The end of script.

В результате выполнения этого скрипта пользователь получит информацию о пользователе paul с машины polyn.kiae.su.

Завершим обзор простейших скриптов небольшой программой на С:

#include <stdlib.h>;
#include <sys/types.h>;
main()
    {
     long i,n,uid;
     char input_ch[1024];
     char *env;
     env = getenv("CONTENT_LENGTH");       /* Here we recieve a length  */
     sscanf(env,"%d",&n);                  /* of input stream and form  */
     for(i=0;i<;n;i++)                     /* command line */
        { input_ch[i] = getchar(); }
     input_ch[i] = '\000';
     printf("Content-type: text/html\n\n"); /* First message of a CGI Programme */
                                            /* This message must be a first one */
                                            /* in output sream.                 */
     printf("<TITLE> Cgi script.(example#1)</TITLE>\n");
     printf("<H3><I> Russian Research Center \"Kurchatov Institute\"<I></H3>\n");
     c_uid = -1;
     sscanf(input_ch,"uid=%ld",&uid); /* Transform input data */
     printf("Input Nuber:%ld.<BR><HR>",uid);
     exit(0);
    }

В приведенном выше примере программа получает данные через стандартный ввод. Это значит, что используется метод доступа POST. Число получаемых байтов указывается в переменной окружения CONTENT_LENGTH. Следует обратить внимание на то, что первой строкой записи в стандартный вывод является строка, определяющая тип информации. В данном случае он определен как текст HTML. Важно также отметить, что в этом операторе вывод завершается двумя переводами на новую строку, т.к. пустая строка должна разделять заголовок и тело сообщения, возвращаемого серверу. Остальные операторы выводят данные в виде HTML-предложений, формируя HTML-документ.

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

Доступ к базе данных под управлением Ingres. Система управления базами данных Ingres является одной из популярных CУБД, работающих в среде операционной системы UNIX. Использование технологии разработки CGI-скриптов помогает построить современный дружественный интерфейс для пользователей WWW к базам данных под управлением данной СУБД. Начнем обсуждение этой возможности с простейших способов обращения с СУБД.

#!/bin/sh
echo Content-type: text/plain
echo
ingres polyn < query
#The end of script

В данном случае запрос заранее подготовлен в виде файла query. Скрипт не получает данных из интерфейсной программы, и действует по жесткой схеме запроса. Аналогично можно вызвать скрипт, выполняющий утилиты Ingres:

#!/bin/sh
echo Content-type: text/plain
echo
helpr polyn
#The end of script

В данном случае скрипт возвращает справку по базе данных polyn.

Естественно, что можно использовать не только тип text/plain, но и text/html. Пример такого использования приведен ниже:

#!/bin/sh
echo Content-type: text/html
echo
echo '< PRE> '
helpr polyn situat
echo '< /PRE> '
#The end of script

Выполнение жестких запросов не очень интересно для пользователя. Он обычно жаждет сформулировать свой собственный запрос. В следующем примере скрипту передается запрос методом доступа GET, который помещен в переменную окружения QUERY_STRING:

#!/bin/sh
echo Content-type: text/html
echo
echo '< PRE> '
echo $QUERY_STRING | tr "+" " " | ingres polyn
echo '< /PRE> '
#The end of script

Прежде всего данные посылаются на предобработку, т.к. все пробелы в запросе заменяются на знак "+" в соответствии с правилами HTTP. После этого фильтра данные поступают на стандартный ввод интерпретатора Ingres и результат работы возвращается пользователю.

Вообще говоря необходима фильтрация и на выходе после Ingres, т.к. вывод содержит неотображаемые символы, например символ '/007', который лучше заменить на что-нибудь отображаемое.

Отчеты могут быть достаточно большими, поэтому имеет смысл ограничить отчет определенным числом строк:

#!/bin/sh
echo Content-type: text/html
echo
echo '< PRE> '
echo $QUERY_STRING | sed -f symbols | ingres polyn | tr "\007" "*" | head 100
echo '< /PRE> '
#The end of script

В данном случае размер отчета ограничен 100 записями. Обратите внимание, в качестве фильтра используется sed, который выполняет правильное преобразование символов из формата HTTP в обычный ASCII. При формировании файла symbols (правила преобразования) следует помнить о порядке выполнения правил преобразования.

Одним из недостатков приведенных выше скриптов является невозможность или достаточно большая сложность преобразования выходной информации Ingres. Если необходимо получить отчет со встроенными в его текст ссылками и картинками, то лучше использовать универсальный язык программирования, например, С.

Программирование на С с использованием EQUEL (препроцессор для доступа к Ingres) позволяет аккуратно разобрать входные данные и построить сложный гипертекстовый отчет. На рисунке 3.29 приведен пример интерфейсной формы.

Рис. 3.29. Результат выполнения скрипта приведен на рисунке 3.30:

Рис. 3.30.

Работа со скриптом imagemap. Скрипт imagemap был разработан для организации доступа к документам по графическим гипертекстовым ссылкам. В общем случае это значит, что в текст HTML-документа встроена картинка. Данная картинка разбита на непересекающиеся области различной формы, обычно круги, прямоугольники или полигоны. С каждой из этих областей связан какой-либо объект (HTML-документ, другая картинка, фильм и т.п.). Выбирая мышью точку на этой картинке, пользователь выбирает объект, связанный с областью, которой принадлежит точка объекта и переходит к просмотру этого объекта. Например, на экране пользователя отображена Европейская часть территории Союза с административными границами республик. Выбирая точку внутри административных границ России, можно получить укрупненную карту европейской части России.

Некоторые HTTP-серверы реализуют функции imagemap самостоятельно, но чаще всего в Сети используют отдельный скрипт. Рассмотрим применение данного скрипта для сервера NCSA. Программа imagemap размещается в директории скриптов, обычно это: "/usr/local/etc/httpd/cgi-bin". В директории "/usr/local/etc/httpd/conf" размещается файл конфигурации скрипта. Для каждой картинки создается еще и файл разбиения картинки на области, адрес которого указывается в конфигурации скрипта.

Для организации стека графических ссылок в документе HTML используют следующую конструкцию:

<A href="http://polyn.net.kiae.su/cgi-bin/imagemap/russia">
<IMG SRC="http://demin.polyn.kiae.su/dss/russia.gif" ISMAP>
</A>

Таким образом, URL скрипта imagemap в качестве последнего компонента пути содержит аргумент, в данном случае "russia". При использовании этой гипертекстовой ссылки программа-клиент добавляет после слова "russia" последовательность типа "?14,25". Первая цифра определяет координату X на картинке относительно левого ее края, а вторая цифра - координату Y относительно верхнего края картинки. При вызове скрипт ищет свой файл конфигурации, который имеет вид:

# метка : адрес файла описания картинки
russia : /usr/local/etc/httpd/cgi-bin/maps/russia.map
brussia : /usr/local/etc/httpd/cgi-bin/maps/brussia.map
....

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

#описание прямоугольника
rect 10 20 100 200
circle 50 50 60 60
poly 10 10 20 20 20 10

Практически все программы imagemap имеют ограничения на число вершин полигона, так для MS-Windows 3.1 ограничение равно 100 точкам.

Для разметки картинок используются специальные вспомогательные программы типа mape-dit, которые позволяют сделать процесс разбивки картинки более наглядным и менее трудоемким.

Общей проблемой, связанной с использованием скриптов, является проблема безопасности. Во-первых, скрипты обычно не пишут сами, как, например, скрипт imagemap, а заимствуют. Понятно, что чужая программа может содержать ошибки. Поэтому лучше пользоваться библиотеками проверенных скриптов, которые рекомендованы, например, World Wide Web Consortium. Во-вторых, если пользователю разрешено иметь свои страницы, то он может получить возможность выполнять свои скрипты на сервере, что тоже приводит к брешам в системе безопасности, особенно если это shell-скрипты. Существуют такие скрипты, которые требуют прав доступа к ресурсам машины. Эти права шире, чем права пользователя "nobody", например, при доступе к базам данных. Все эти моменты следует учитывать, как при написании скриптов, так и при разрешении использования различным группам пользователей.

Как правило, новые возможности WWW опробуются на скриптах, а затем, если эти возможности широко используются в практике, они включаются в стандарты различных компонентов системы и могут быть реализованы в новых возможностях серверов, как например imagemap и системы безопасности. Скрипты позволяют новым энтузиастам Сети приобщиться к сообществу и внести свою лепту в развитие системы.

Назад | Содержание | Вперед

 

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...