Серверные расширения CGI и ISAPI

Языки JavaScript, VBScript и PerlScript

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

С этой целью был разработан (фирма Netscape Communication Corp., первоначальное название LiveScript) язык JavaScript (не имеющий прямого отношения к Java), язык JavaScript является средством создания активных WEB-страниц непрофессионалами. Фирма MS реализовала в своем броузере MSIE поддержку языка JScript (весьма близкому к JavaScript), давняя приверженность главы MS к Basic’у привела к включению в упомянутый броузер поддержку языка VBScript (по возможностям близкого JavaScript). Так же как и Java, программы на JavaScript и VBScript позволяют не только создавать активные (изменяющиеся предсказанным образом в процессе работы) WEB-страницы, но и снижают поток данных между рабочей станцией и сервером WEB (что благоприятно сказывается на скорости реакции сервера).

Ниже показан HTML-сценарий с встроенным кодом на JavaScript

<HTML>

<HEAD>

<TITLE>Динамическое создание WEB-страницы</TITLE>

</HEAD>

<BODY>

<H1>JavaScript test</H1>

<SCRIPT LANGUAGE="JavaScript">

document.write("Этот текст динамически сгенерирован " +

"программой на JavaScript");

</SCRIPT>

</BODY>

</HTML>

Здесь код на JavaScript заключен между тегами <SCRIPT LANGUAGE=“JavaScript”> и </SCRIPT> и вызывает метод write объекта document, причем метод (по умолчанию) вызывается при загрузке HTML-файла броузером, что приводит к генерации соответствующего текста (и, соответственно, индикации его в окне броузера).

Язык JavaScript позволяет связать вызов конкретной функции с некоторым событием (загрузкой или выгрузкой файла, перемещением указателя ‘мыши’ над заданным участком окна броузера, щелчком кнопки ‘мыши’ над графическим объектом и др.), что позволяет придать WEB-странице определенную ‘интеллектуальность’.

Например, следующий фрагмент HTML-сценария связывает вызов JavaScript-процедуры MakeOnLoad с загрузкой файла в броузер, а процедуры MakeOnUnload - с выгрузкой (например, в связи с переходом к следующей странице).

. . .

<BODY onLoad="MakeOnLoad()" onUnload="MakeOnUnload()">

. . .

Следующий пример сценария служит для выдачи окна запроса с двумя кнопками - ‘Ok’ и ‘Cancel’ (при щелчке левой кнопкой ‘мыши’ по выделенному словосочетанию-ссылке ‘Желаете выгрузить’) и совершения некоторого действия (в данном случае выгрузки файла OMD.RAR на компьютер клиента) при положительном ответе

. . .

<A HREF="JavaScript:

if (confirm('Вы действительно желаете выгрузить на свой ' +

'компьютер файл OMD.RAR размером аж 330 kb ?'))

location.href = './bin/omd.rar';">

Желаете выгрузить</A> на Ваш компьютер пакет OMD ?

. . .

В языке JavaScript определены функции работы с числами, строками, массивами, определения типа броузера, анализа и изменения содержимого WEB-страниц, диалога с пользователем, обработки данных форм (перед отсылкой на сервер), взаимодействия с апплетами Java и др., поддерживается обьектно-ориентированный подход. Для отладки JavaScript-сценариев предлагается отладчик MS Script Debugger.

Язык VBScript в целом обладает сходными с JavaScript возможностями, но имеет Basic-подобный синтаксис и поддерживается только броузером MSIE.

Желающим более подробно ознакомиться с концепциями и языком JavaScript рекомендуются опубликованные работы и ресурсы Сети, некоторые (несложные) конструкции JavaScript можно выгрузить (в составе HTML-сценариев) с сайта автора http://pilger.mgapi.ru. Более серьезные примеры JavaScript-приложений можно получить с адресов

· http://www.cris.com/raydaly/hjdemo.shtml

· http://www.homepages.com/fun/I040EZ.html

· http://www.geocities.com/SiliconValley/7116/jv_cale.html

· http://www.best.com/nessus/jstodasy.html

В отличие от Java, коды JavaScript и VBScript практически безопасны с точки зрения совершения несанкционированных действий на компьютере пользователя.

Некоторые WEB-броузеры (например, MSIE версий выше 4) способны интерпретировать встроенный в HTML-код язык PerlScript. Часто вместо создания полномасштабной CGI-программы возможно ограничиться внедрением текста на PerlScript в WEB-страницу (ниже приведен пример простейший HTML-страницы с выводом строки посредством PerlScript-кода).

<!DOCTYPE HTML PUBLIC “-//W#C//DTD HTML 3.2//EN”>

<HTML>

<HEAD>

<TITLE>My first PerlScript example</TITLE>

</HEAD>

<BODY>

<H2>PerlScript example</H2>

<SCRIPT LANGUAGE="PerlScript">

$window->document->write("Hello, PERL !");

</SCRIPT>

</BODY>

</HTML>

Серверные расширения CGI и ISAPI

Серверные расширения CGI (Common Gateway Interface - стандартный шлюзовый интерфейс) и ISAPI (Internet Server API, также NSAPI - Netscape Server API) предназначены для запуска внешних программ под управление WEB-сервера; внешняя программа получает информацию через протокол HTTP от удаленного пользователя, обрабатывают ее (например, осуществляют SQL-запрос к базе данных) и возвращают результат обработки обратно в виде ссылки на существующий HTML-документ или в виде динамически созданной HTML-страницы.

Передача информации от удаленного пользователя происходит следующим образом

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

· Данные поступают на сервер и обрабатываются (возможно, весьма изощренными) приложениями CGI или ISAPI.

· CGI/ISAPI-приложение генерирует (обычно динамически) HTML-документ (файл) и пересылает его обратно удаленному пользователю (где этот документ интерпретируется и визуализируется броузером).

Ниже приведен пример HTML-кода простой формы с двумя полями ввода (имена полей ‘text1’ и ‘text2’) и кнопкой для отсылки сообщений серверу

. . .

Образец простейшей формы

<FORM METHOD=GET ACTION=“http://www.my_server.ru/cgi/form.exe”>

<TABLE border=0>

<TR>

<TD>Имя :</TD>

<TD><INPUT TYPE=text NAME="text1" VALUE="Текст 1" size=33>

</TD></TR>

<TR>

<TD>Пароль :&nbsp;</TD>

<TD><INPUT TYPE=text NAME="text2" VALUE="Текст 2" size=33>

</TD></TR>

<TR>

<TD>&nbsp;</TD>

<TD><INPUT TYPE=submit VALUE="Послать данные серверу">

</TD></TR>

</TABLE>

</FORM>

. . .

На рис.7.12 показано отображение этой формы броузером (хорошо видны два поля ввода и кнопка отсылки введенных в эти поля данных на сервер).

Параметр ACTION описания формы определяет действие, выполняющееся над присланной на сервер информацией (в данном случае указан путь к программе CGI, которая будет выполнять обработку данных). Параметром METHOD выбирается один из двух методов передачи данных серверу WWW - при значении этого параметра GET указанная в параметре ACTION программа CGI получит данные из формы через переменную среды с именем QUERY_STRING, в случае METHOD=POST программа CGI получит данные из формы через стандартный поток ввода stdin.

С целью использования языков программирования, не поддерживающих (в явном виде) стандартных потоков ввода и вывода (например, Pascal) разработана спецификация WinCGI, согласно которой в передаче данных используются привычные для Windows инициализационные файлы [5].

Возможна прямая посылка серверу строки QUERY-STRING в соответствие со следующим URL (через знак вопроса после имени обрабатывающей запрос CGI-программы указывается пересылаемая строка)

http://www.my_server.ru/cgi/search.exe?query-string

При использовании METHOD=GET данные формы поступают на сервер в виде значения переменной среды QUERY_STRING в следующем формате:

Имя1=Значение1&Имя2=Значение2&Имя3=Значение3

Здесь в качестве имен используются значения параметров NAME формы, вместо значений подставляются данные из соответствующих именам полей. Программа CGI должна просканировать содержимое текстовой строки переменной cреды QUERY_STRING и по имени поля найти нужное значение, введенное в это поле пользователем. Адрес заданной строки переменной среды в программе легко получить с помощью C-функции getenv

char * szQueryString;

szQueryString = getenv("QUERY_STRING");

Передаваемая в переменной среды QUERY_STRING строка закодирована с использованием т.н. кодировки URL (символы пробелов заменяются на символ ‘+’, для представления кодов управляющих и некоторых других символов используется конструкция вида %xx, где хх - шестнадцатиричный код символа в виде двух ASCII-символов); CGI-программа должна выполнить обратную перекодировку.

Серверные расширения CGI и ISAPI - student2.ru Рисунок 7.12 — Отображение простейшей формы броузером.

При использовании METHOD=POST программа CGI получает данные из формы через стандартный поток ввода stdin (для чтения удобно использовать С-функции fread или scanf) в аналогичном методу GET формате, причем количество байт в stdin передается CGI-программе через переменную среды с именем CONTENT_LENGTH:

int Size;

Size = atoi(getenv("CONTENT_LENGTH")); // получить длину строки

char szBuf[8196];

fread(szBuf, Size, 1, stdin); // прочитать полученные данные

Метод GET применяется относительно редко (длина строки QUERY_STRING ограничена), метод POST более предпочтителен.

Вне зависимости от примененного метода передачи данных (GET или POST) результат своей работы программа CGI должна направлять в стандартный поток вывода stdout (при этом WWW-сервер гарантирует возврат данных броузеру локального компьютера). Ниже приведен пример динамической генерации CGI-программой документа HTML и направления его на stdout

. . .

printf("Content-type: text/html\n\n"); //упрощенный пролог HTML

printf("<!DOCTYPE HTML PUBLIC \""-//W3C//DTD HTML 3.2//EN\"">");

printf("<HTML><HEAD>

<TITLE>My first dinamic HTML-page</TITLE>

</HEAD><BODY>");

printf("<H1>Результаты обработки данных формы:</H1>");

. . .

. . .

printf("</BODY></HTML>");

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

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

Заметим, что с помощью CGI-программ легко реализуются, например, счетчики числа посещений страниц; в качестве языка программирования CGI-программ часто используют интерпретатор языка Perl (Practical Extraction and Report Language, иногда в шутку Pathologically Eclectic Rubbish Lister, см. InterNet-адреса www.perl.com, http://www.cpan.org, http://orwant.www.media.mit.edu/the_perl_journal, http://www.tpj.com), хотя может быть применен практически любой язык программирования (особенно удо­бен C/C++).

Недостатком приложений CGI является то, что для обработки каждого запроса WWW-сервером он запускает новое CGI-приложение (новый процесс), а т.к. современные сервераодновременно могут обрабатывать много запросов, ресурсы машины-сервера (например, объем оперативной памяти) быстро истощаются (не говоря уже о снижении производительности сервера). От подобного недостатка свободен метод ISAPI, основанный на обработке запросов динамически загружаемыми (из DLL-библиотек) функциями (недостаток - т.к. ISAPI-расширение выполняется в том же адресном пространстве, что и сам WEB-сервер, критическая ошибка ISAPI-приложения обычно вызывает крах сервера). В отличие от CGI, ISAPI-приложение получает данные не из стандартного потока, а с помощью специально предназначенной для этого функции интерфейса ISAPI; вместо стандартного потока вывода также применяется специальная функция.

Некоторые сервера (например, Apache) содержат встроенный Perl, при этом для каждого поступающего CGI-запроса сервер создает новый поток (вместо нового процесса); это значительно ускоряет выполнение CGI-запросов указанным сервером. Для работы под Windows’NT разработаны (см. http://www.activeware.com) пакеты PerlScript (разработка сценариев ActiveX) и PerlIS (динамически вызываемая библиотека ISAPI-интерфейса.

Известны как расширения ISAPI (по функциям аналогичны CGI-расширениям сервера), так и фильтры ISAPI (фактически являющиеся брандмауэрами, применяются для шифрования или перекодировки проходящих через сервер данных, компрессии информации, сбора статистических данных о пользователях, проверки прав доступа и др.).

При использования метода ISAPI имя соответствующего DLL-файла описывается в параметре ACTION формы (аналогично CGI), также описывается параметр METHOD, однако сами присланные на сервер данные могут быть получены с помощью специально зарезервированных функций GetServerVariable (чтение значений переменных среды) и ReadClient (собственно чтение присланных данных), отсылка же данных (как и при использовании CGI, обычно в виде динамически создаваемых HTML-файлов) производится функциями WriteClient и ServerSupportFunction.

Заметим, что CGI- и ISAPI-программы потенциально являются источниками снижения безопасности функционирования WEB-серверов. Ниже приведено несколько WEB-адресов, посвященных проблеме безопасности:

· http://www.w3.org/Security/Faq/www-security-faq.html

· http://www.perl/com/CPAN-local/doc/FAQs/cgi/perl-cgi-faq.html

· http://stars.com/Authoring/Scripting/Sequrity

· http://www.go2net.com/people/paulp/cgi-sequrity/safe-cgi.txt

Мощным средством для упрощения процесса реализации функциональности и расширения возможностей технологии CGI является язык PHP/FI (Персональные инструментальные средства для Домашней Страницы / Интерпретатор Форм), предложения которого встраиваются непосредственно в текст HTML-страницы и выполняются процессом, инициализированным сервером (обычно Apache). PHP существенно упрощает обработку запросов от форм и анализ SQL-запросов, допускает добавление пользовательских функций (обычно написанных на C). Использование PHP повышает эффективность обработки запросов (CGI-программа не стартует, PHP-код выполняется одним из серверных процессов), при этом повышается уровень защиты данных и конфигурируемость серверного ПО. Первым признаком того, что страница обрабатывается PHP, является добавление нижнего колонтитула с информацией о количестве обращений к данной странице (если программа скомпилирована с опцией регистрации доступа).

Наши рекомендации