Большая часть нашего общения с WWW сводится к тому, что обозреватель, работающий на компьютере-клиенте,
передает Веб-серверу URI Веб-страницы, сервер находит ее в Сети и передает обозревателю, а тот эту страницу отображает.
Этот способ общения вполне достаточен для обычного серфинга, но существует обширный круг задач, требующих более
развитой технологии взаимодействия сервера с клиентом, например:
- обращение к поисковой системе с целью поиска узлов, содержащих определенную информацию;
- запрос к базе данных с целью выборки данных, отвечающих заданному критерию;
- передача серверу результатов заполнения пользователем формы с целью оплаты отобранного товара
или проведения банковской транзакции.
Все эти примеры, по сути дела, сводятся к одной задаче. Нам нужна технология, позволяющая:
- запустить с компьютера клиента на сервере определенную программу (обычно называемую сценарием
сервера);
- передать ей (опять же от клиента) определенные параметры;
- передать результаты работы программы от сервера обратно клиенту.
Для решения этой задачи нужен единый интерфейс клиент-сервер, который не зависел бы ни от платформы,
ни от операционной системы, ни от языка программирования, на котором реализован сценарий сервера.
Такой несложный интерфейс был создан в 1993 г. в NCSA (The National Centre for Supercomputing
Applications) под названием CGI (Common Gateway Interface) и продолжает использоваться без существенных
изменений по сей день. Мы опираемся в последующем изложении на спецификацию CGI/1.1, ревизию
03 от 25 июня 1999 г. Общая схема взаимодействия клиента с сервером иллюстрируется следующим рисунком:
Вспомним, что всякий запрос передается от обозревателя к серверу в форме URI, общий вид которого
таков (подробности см. в Приложении 2):
протокол://пользователь@сервер:порт/путь?запрос
Суть CGI состоит в том, что он фиксирует стандартные имена метапеременных, которые
сервер должен заполнить, анализируя URI запроса. Эти метапеременные представляют собой текстовые
строки, которые должны быть доступны запускаемому сценарию; конкретная реализация механизма
доступа к переменным зависит от операционной системы. Согласно спецификации CGI запрос на запуск
сценария будет выглядеть так:
протокол "://" SERVER_NAME ":" SERVER_PORT SCRIPT_NAME
PATH_INFO "?" QUERY_STRING
где SERVER_NAME, SERVER_PORT, SCRIPT_NAME, PATH_INFO и QUERY_STRING
метапеременные, соответствующие составным элементам URI и описанные ниже.
Примечания.
- Протокол URI и протокол CGI не всегда совпадают. Например, если доступ к ресурсу
осуществляется через защитный механизм SSL (Secure Sockets Layer), то именем протокола URI
будет https, а именем протокола CGI по-прежнему http. Впрочем,
CGI не содержит механизмов, позволяющих сценарию извлечь имя протокола, поэтому можно считать,
что оно всегда http. Кроме того, URI запроса к CGI не может содержать закладок.
- В действительности, URI сценария содержит не SCRIPT_NAME и PATH_INFO, а их
кодированную форму. Дело в том, что URL может состоять только из символов базовой латиницы,
а в запросе могут присутствовать и иные символы. В этом случае они преобразуются в кодировку
UTF-8, как описано в Приложении 2, а затем передаются серверу.
Как отмечалось выше, сценарием может быть исполняемый модуль, написанный на любом языке (например,
на C++). Но чаще всего в качестве сценария выступает интерпретируемый модуль (например, на языке
PERL). При этом операционная система сервера распознает тип сценария и вызывает соответствующий
интерпретатор (например, perl.exe).
Далее, сервер обязан извлечь информацию из URI запроса и разместить ее в метапеременных. Имена
метапеременных не должны зависеть от регистра, но это также определяется системой. Поэтому лучше
всегда писать их прописными буквами, как делаем мы в этом справочнике. Значения метапеременных
должны считаться зависящими от регистра.
Следующие имена метапеременных являются стандартными и должны формироваться всеми серверами,
поддерживающими интерфейс CGI.
Таблица П24.1. Стандартные метапеременные CGI
AUTH_TYPE |
Тип авторизации. Если сервер признал полномочия пользователя, значение этой переменной
"Basic", в противном случае оно не определено. |
CONTENT_LENGTH |
Десятичное число байтов в теле сообщения, если оно присоединено к запросу. |
CONTENT_TYPE |
Тип MIME тела сообщения, если оно присоединено к запросу. |
GATEWAY_INTERFACE |
Текущая версия CGI. В настоящее время это "CGI/1.1" |
PATH_INFO |
Указывает на ресурс или подресурс, который должен быть возвращен сценарием. Это часть
URI между именем сценария и строкой запроса. |
PATH_TRANSLATED |
Значение PATH_INFO, в котором все виртуальные имена отображены в реальные каталоги сервера. |
QUERY_STRING |
Строка запроса к сценарию. Это все, что следует в URI запроса после "?". |
REMOTE_ADDR |
IP-адрес клиента. |
REMOTE_HOST |
Полное имя домена клиента. |
REMOTE_IDENT |
Если Веб-сервер поддерживает идентификацию по RFC
1413 , сюда
заносится имя удаленного пользователя. Используется только для регистрации. |
REMOTE_USER |
Если AUTH_TYPE = "Basic", то здесь содержится имя пользователя, переданное
клиентом и проверенное сервером на наличие прав доступа. |
REQUEST_METHOD |
Метод запроса HTTP ("GET", "HEAD",
"POST", "PUT", "DELETE", "OPTIONS", "TRACE"). |
SCRIPT_NAME |
Имя запускаемого сценария. |
SERVER_NAME |
Имя или IP-адрес сервера. |
SERVER_PORT |
Порт TCP/IP, на который пришел запрос. |
SERVER_PROTOCOL |
Имя и версия протокола, связанного с запросом. Обычно это "HTTP/1.1". |
SERVER_SOFTWARE |
Имя и версия Веб-сервера в формате "имя/версия". |
Если запрос помимо URI содержит присоединенные данные, то сервер должен занести размер этих
данных в байтах в переменную CONTENT_LENGTH и обеспечить сценарию доступ к этим данным. Если
не оговорено иное, доступ осуществляется через дескриптор файла "стандартный ввод"
(stdin).
Сценарий считывает переданные ему данные, при необходимости анализирует метапеременные и формирует
документ, который сервер должен передать клиенту.
Сценарий всегда должен вернуть какой-либо результат серверу, а сервер должен обеспечить механизм
передачи результатов от сценария к серверу. Если не оговорено иное, эта передача осуществляется
через дескриптор файла "стандартный вывод" (stdout). Сервер, в свою очередь, формирует
из полученных от сценария данных стандатный HTTP-отклик и передает его клиенту.
Результатом работы сценария может быть либо сгенерированный HTML-документ, либо указание серверу
вернуть пользователю определенный ресурс. Данные, передаваемые сценарием серверу, начинаются со
служебного заголовка, состоящего из текстовых строк и заканчивающегося пустой строкой (т. е.
строкой, состоящей из LF или CR/LF). Служебный заголовок может содержать три директивы,
аналогичные полям заголовка HTTP:
Поле |
Описание |
Content-Type |
Содержит тип MIME возвращаемого документа. |
Location |
Возвращает URI ресурса. Используется в том случае, когда сценарий передает серверу
не сформированный документ, а ссылку на ресурс. |
Status |
Возвращает код состояния в формате число строка,
где число номер кода состояния, а строка соответствующее
сообщение. Этот код состояния заносится в строку состояния HTTP-отклика. |
Пример документа, сформированного сценарием:
Content-type: text/html; charset=windows-1251
Status: 200 OK
<HTML><HEAD>
<TITLE>Вывод HTML из CHI-сценария</TITLE>
</HEAD><BODY>
<H1>Пример</H1>
<P>Как вам <STRONG>это</STRONG> нравиться?</P>
</BODY></HTML>
Реальные примеры CGI-сценариев приведены в гл. 6.13.
|