Разработка CGI-программ
Самым простым и исторически самым первым способом создания динамических ресурсов для сети Интернет является использование интерфейса CGI.
CGI-интерфейс
Common Gateway Interface (CGI) является стандартом интерфейса внешней прикладной программы с Web сервером. Их взаимодействие иллюстрируется рис.4.1.
Рис. 4.1. Распределение функций между уровнями с использованием интерфейса CGI
Клиентская часть приложения представляет собой HTML-документ, в котором реализован интерфейс с пользователем. Реализуется в основном посредством форм, хотя могут использоваться и другие элементы, в том числе скрипты и апплеты.
Серверная часть состоит из исполняемого модуля, решающего основные задачи обработки данных, поступающих от клиентской части, формирования ответа в формате HTML, и т.д. Такой модуль называется cgi-модулем или расширением сервера.
Сам интерфейс CGI представляет собой правила взаимодействия сервера с внешним по отношению к нему модулем (cgi-модулем). Он определяет 4 информационных потока (рис. 4.2):
|
|
· переменные окружения;
· стандартный входной поток;
· стандартный выходной поток;
· командная строка.
Рис. 4.2. CGI-интерфейс.
Переменные окружения в среде любой ОС служат для связи между процессами, они представляют собой набор специальных переменных, значения которых устанавливаются перед запуском программы и доступны программе в ходе выполнения. Состав переменных и их имена зависят от процесса, запускающего данную программу.
Этих переменных достаточно много, они содержат различные данные, в частности:
SERVER_SOFTWARE - содержит информацию о Web-сервере (название/версия);
GATEWAY_INERFACE - содержит информацию о версии CGI(CGI/версия);
CONTENT_LENGTH - значение этой переменной соответствует длине стандартного входного потока в символах;
CONTENT_TYPE - эта переменная специфицирована для запросов содержащих дополнительную информацию, таких как HTTP POST и PUT, и содержит тип данных этой информации;
REQUEST_METHOD - метод запроса, который был использован "POST","GET","HEAD" и т.д.;
PATH_INFO - значение переменной содержит полученный от клиента виртуальный путь до cgi-модуля;
PATH_TRANSLATED -значение переменной содержит физический путь до cgi-модуля, преобразованный из значения PATH_INFO;
QUERY_STRING - значение этой переменной соответствует строке символов следующей за знаком "?" в URL соответствующему данному запросу;
HTTP_USER_AGENT - название программы просмотра, которую использует клиент при посылке запроса.
Аргументы командной строки. Кроме переменных окружения запускаемой программе передается список параметров, помещаемых в командную строку при запуске. СGI-модуль в командной строке от сервера получает:
|
|
· остаток URL после имени cgi-модуля в качестве первого параметра (первый параметр будет пуст, если присутствовало только имя cgi-модуля);
· список ключевых слов в качестве остатка командной строки для скрипта поиска или чередующиеся имена полей формы с добавленным знаком равенства и соответствующих значений переменных.
Стандартный входной поток. Состав данных, направляемых сервером во входной поток СGI-модуля, зависит от использованного клиентом метода запроса.
В случае метода запроса POST данные передаются как содержимое HTTP запроса в следующей форме:
name=value&name1=value1&...&nameN=valueN
где name - имя переменной,
value - значение переменной,
N - количество переменных
При этом устанавливаются значения переменных окружения CONTENT_LENGTH и CONTENT_TYPE.
Таким образом, если в результате использования формы с аргументом тега FORM - METHOD="POST" сформирована строка данных firm=МММ&price=100023, то сервер установит значение CONTENT_LENGTH равным 21 и CONTENT_TYPE в application/x-www-form-urlencoded, а в стандартный поток ввода посылается блок данных.
В случае запроса метода GET, строка данных передается как часть URL. Например,
http://host/cgi-bin/script?name1=value1&name2=value2
В этом случае переменная окружения QUERY_STRING принимает значение name1=value1&name2=value2, а во входной поток ничего не посылается.
Стандартный выходной поток. СGI-модуль выводит информацию в стандартный выходной поток. Этот вывод может представлять собой или документ, сгенерированный cgi-модулем, или инструкцию серверу, где получить необходимый документ.
Вывод cgi-модуля должен начинаться с заголовка содержащего определенные строки и завершаться двумя символами CR ("\n", код 0x10). Эти стоки воспринимаются как директивы серверу. Строки, не являющиеся директивами сервера, посылаются непосредственно клиенту. CGI спецификация определяет три директивы сервера:
Content-type - MIME или тип возвращаемого документа;
Location - указывает серверу, что возвращается не сам документ, а ссылка на него;
*Status - задает серверу HTTP/1.0 строку-статус, в которой кодируется различная информация (например, об успешном завершении операции).
При отправке клиенту HTML-документа директива имеет вид Content-Type:text/html\n\n.
Если будет передан URL, то директива может выглядеть, например, так Location: http://host/file.htm, и сервер вернет клиенту заданный этим путем документ, как если бы клиент запрашивал этот документ непосредственно.
Обычно CGI–программы размещаются в каталоге со стандартным именем (чаще всего cgi-bin). В этом случае для идентификации достаточно имени файла (без расширения). Ссылка на этот ресурс может выглядеть, например, так: http://www.orp.com/cgi-bin/myscript. Иногда сервер не содержит специального каталога. В этом случае файлы программ могут располагаться в произвольном месте, путь к которому включен в URL. Но при этом необходимо указывать и расширение файла: http://www.orp.com/mucat/myscript.exe. Для некоторых серверов (например, IIS 7) может потребоваться задавать разрешение на выполнение с указанием имени программы.
Использоваться такие ссылки могут в любом атрибуте, допускающем URL (href, src). При этом после самого адреса могут размещаться данные, которые будут переданы серверу вместе с URL. Данные начинаются с символов, следующих за знаком "?", например,
<a href=”/mycgi/cd2.exe?date>вызов CGI</a>
В этом случае серверу будет отправлена строка /mycgi/cd2.exe?date. Сервер передает эту строку CGI-программе через переменные окружения (в PATH_INFO будет URL, а в QUERY_STRING – строка "date").
После принятия и расшифровки запроса выполняется динамическое формирование cgi-модулем HTML-документа, например, таблицы выборки из базы данных.
Для формирования ответа клиенту, cgi-модуль должен выдать в стандартный выходной поток заголовок, состоящий из строки:
Content-type: text/html и пустой строки (двух символов CR)
|
|
После этого заголовка может следовать любой текст в формате HTML (или другого языка, который может интерпретироваться браузером, например, XML).
У CGI имеется несколько разновидностей, в частности, WinCGI, для которого данные запроса и ответа передаются не через входной поток, а через запись в файлы. Параметры запроса записываются сервером в файл, запускается программа, читает и обрабатывает запрос, записывает ответ в файл (HTML), который сервер направляет клиенту.
Языком написания CGI-программ может быть любой, однако при использовании языков с транслятором интерпретирующего типа (Perl, PHP, VBAScript и др.) сервер должен содержать соответствующий интерпретатор (обычно в виде подключаемого модуля). При использовании языка с транслятором компилирующего типа (Pascal, C++, C#, Java), исполняемый модуль должен создаваться в консольном режиме.
Пример 4.1.
Создать на языке C# программу, выводящую клиенту приветствие в ответ на запрос.
Код программы:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace cgi1
{
class Program
{
static void Main(string[] args)
{
Console.Write("Content-Type:text/html\n\n");
Console.WriteLine("<html>");
Console.WriteLine("<head>");
Console.WriteLine("<title>Простейшая CGI-программа</title>");
Console.WriteLine("</head>");
Console.WriteLine("<body>");
Console.WriteLine("<h1>Вас приветствует CGI-программа!</h1>");
Console.WriteLine("</body>");
Console.WriteLine("</html>");
}
}
}
Программа должна быть откомпилирована, а полученный исполняемый файл (например, proba.exe) помещен в соответствующий каталог сервера. Набрав в строке адреса браузера URL (что-нибудь вроде http:// localhost/cgi-bin/proba.exe), который указывает путь к созданному файлу, увидим в окне сгенерированную страницу.
Программа, которая должна получить от клиента данные для обработки, выглядит несколько сложнее за счет того, что требуется выполнять разбор получаемых строк.