Переменные среды CGI


Оглавление (нажмите, чтобы открыть):

Переменные среды CGI

На этом шаге мы рассмотрим переменные среды CGI .

В зависимости от метода данные формы передаются в CGI -программу или через стандартный ввод (POST) , или через переменную среды QUERY_STRING (GET) . Помимо этих данных CGI -программе доступна и другая информация, поступившая от клиента в заголовках запроса или предоставленная Web -сервером. Эта информация сохраняется в переменных среды UNIX . С некоторыми из них мы уже познакомились ранее. В таблице 1 перечислены переменные, обычно используемые в CGI .

Таблица 1. Переменные среды CGI
Переменная среды Описание
GATEWAY_INTERFACE Версия CGI , которую использует сервер
SERVER_NAME Доменное имя или IP -адрес сервера
SERVER_SOFTWARE Имя и версия программы-сервера, отвечающей на запрос клиента (например, Apache 1.3 )
SERVER_PROTOCOL Имя и версия информационного протокола, который был использован для запроса (например, HTTP 1.0 )
SERVER_PORT Номер порта компьютера, на котором работает сервер (по умолчанию 80)
REQUEST_METHOD Метод, использованный для выдачи запроса (GET, POST)
PATH_INFO Дополнительная информация о пути
PATH_TRANSLATED Та же информация, что и в переменной PATH_INFO с префиксом, задающим путь к корневому каталогу дерева Web -документов
SCRIPT_NAME Относительное маршрутное имя CGI -сценария (например, /cgi-bin/program.pl )
DOCUMENT_ROOT Корневой каталог дерева Web -документов
QUERY_STRING Строка запроса — информация, переданная в составе URL -запроса после символа «?»
REMOTE_HOST Имя удаленной машины, с которой сделан запрос
REMOTE_ADDR IP -адрес удаленной машины, с которой сделан запрос
REMOTE_USER Идентификационное имя пользователя, посылающего запрос
CONTENT_TYPE Медиа-тип данных запроса, например, «text/html»
CONTENT_LENGTH Количество байт в теле запроса, переданных в CGI -программу через стандартный ввод
HTTP_HOST Хост-имя компьютера, на котором работает сервер
HTTP_FROM Адрес электронной почты пользователя, направившего запрос
HTTP_ACCEPT Список медиа-типов, которые может принимать клиент
HTTP_USER_AGENT Браузер, которым клиент пользуется для выдачи запроса
HTTP_REFERER URL документа, на который клиент указывал перед обращением к CGI -программе

Замечание . Имена переменных среды CGI на разных Web -серверах могут различаться. Следует обратиться к документации на соответствующий сервер.

CGI -программа на языке Perl имеет доступ к переменным среды через специальный предопределенный хеш-массив %ENV , к элементам которого можно обратиться по ключу, совпадающему с именем переменной среды. Ниже приведены пример CGI -сценария, формирующего HTML -документ с информацией о всех установленных переменных среды, и отображение этого документа в окне браузера.

Переменные среды CGI

Прежде чем перейти к примерам программ CGI, мы изучим переменные среды, которые формируются для этих программ перед запуском. Через эти переменные помимо данных из полей форм передается и другая очень важная информация, которую не всегда следует игнорировать.

Изучение переменных среды мы начнем с того, что просмотрим их значение с помощью простейшей программы CGI, созданной с использованием языка пакетных заданий операционной системы Microsoft Windows NT, а проще говоря, с помощью обыкновенного файла с расширением имени bat.

Для запуска этой “программы” мы подготовили форму, исходный текст которой представлен в листинге 7.2.

Листинг 7.2. Файл chap7\viewenv\viewenv.htm

Форма выглядит так, как это показано на рис. 7.3.

Рис. 7.3. Форма для запуска программы CGI просмотра значений переменных среды

Обратите внимание, что после имени программы CGI через разделительный символ “?” указана строка параметров param1, которая может быть получена и проанализирована программой CGI.

Исходный текст программы CGI приведен в листинге 7.3.

Листинг 7.3. Файл chap7\viewenv\test.bat

В первой строке программа выводит в стандартный поток вывода STDOUT строку заголовка HTTP. Эта строка описывает тип передаваемых данных как text/plain, то есть обычный текст без оформления с использованием операторов HTML.

Вторая строка выводит в стандартный поток вывода пустую строку, которая отделяет заголовок HTTP от передаваемых данных.

Третья строка выводит путь к загрузочному файлу программы CGI и параметры, полученные ей при запуске.

И, наконец, в последней строке вызывается команда SET, которая выводит в поток STDOUT значения всех переменных среды, определенных в системе перед запуском программы.

Результат работы нашей программы CGI показан на рис. 7.4.

Рис. 7.4. Результат работы программы CGI, отображающей значения переменных среды

Ниже мы привели полный листинг, полученный при работе нашей программы CGI:

В этом листинге отображаются переменные среды, определенные специально для программы CGI сервером Microsoft Internet Information Server, а также переменные среды, стандартные для операционной системы Microsoft Windows NT.

Рассмотрим по отдельности назначение переменных среды. Заметим, что набор переменных, создаваемых при запуске программы CGI, зависит от конкретной реализации сервера WWW.

Технология WWW допускает защиту страниц HTML, когда доступ к отдельным страницам предоставляется только для отдельных пользователей при предъявлении пароля. При этом используется так называемая система аутентификации, или проверки подлинности идентификатора пользователя.

Переменная среды AUTH_TYPE содержит тип идентификации, который применяется сервером. Например, для сервера WWW типа Microsoft Information Server при включении аутентификации в этой переменной будет храниться строка “NTLM”.

В этой переменной находится версия интерфейса CGI, с которой работает данный сервер. В нашем случае интерфейс имеет версию 1.1.

В этой переменной перечислены типы данных MIME, которые могут быть приняты навигатором от сервера WWW. Из приведенного выше листинга видно, что сервер Microsoft Internet Information Server может передать навигатору Microsoft Internet Explorer (который был использован для работы с программой CGI) графические изображения (image) в формате gif, jpeg, pjpeg, x-xbitmap. Подробно эти типы данных описаны в спецификации протокола MIME, рассмотрение которой выходит за рамки нашей книги.

В переменную HTTP_REFER записывается адрес URL документа HTML, который инициировал работу программы CGI. В нашем случае этот документ был записан на локальном диске компьютера в каталоге C:\!websrv\Sample\Chap7\viewenv.

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

Разрешение видеоадаптера, установленное в компьютере пользователя.

Допустимое количество цветов в системе пользователя.

Операционная система, под управлением которой работает навигатор.

Тип центрального процессора в компьютере удаленного пользователя.

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

Имя узла, на котором работает сервер WWW.

Метод кодирования, который может быть использован навигатором для формирования ответа серверу WWW.

Информация авторизации от навигатора. Используется навигатором для собственной аутентификации в сервере WWW.

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

Специальные команды серверу WWW.

Количество байт данных, которые программа CGI должна получить от навигатора.

Тип данных, присланных навигатором.

Путь к виртуальному каталогу, в котором находится программа CGI.

Как правило, при настройке сервера WWW администратор выделяет один или несколько каталогов для хранения расширений сервера в виде программ CGI или ISAPI. Для файлов, записанных в такие каталоги, устанавливается доступ на запуск.

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

Физический путь к программе CGI.

Строка параметров, указанная в форме после адреса URL программы CGI после разделительного символа “?”.

Адрес IP узла, на котором работает навигатор удаленного пользователя.

Доменное имя узла, на котором работает навигатор удаленного пользователя. Если эта информация недоступна (например, для узла не определен доменный адрес), вместо доменного имени указывается адрес IP, как в переменной REMOTE_ADDR.

Имя пользователя, которое используется навигатором для аутентификации. Используется только в том случае, если сервер WWW способен работать с аутентификацией и программа CGI отмечена как защищенная.


Метод доступа, который используется для передачи данных от навигатора серверу WWW. В своих примерах мы используем методы доступа GET и POST, хотя протокол HTTP допускает применение и других методов доступа, например, PUT и HEAD.

В эту переменную записывается путь к виртуальному каталогу и имя программы CGI. Анализируя эту переменную, программа CGI может определить путь к своему загрузочному файлу.

Доменное имя сервера WWW или адрес IP сервера WWW, если доменное имя недоступно или не определено.

Имя и версия протокола, который применяется для выполнения запроса к программе CGI.

Номер порта, на котором навигатор посылает запросы серверу WWW.

Название и версия программного обеспечения сервера WWW. Версия следует после названия и отделяется от последнего символом “/”.

Имя, с которым пользователь подключился к серверу WWW. Используется только в том случае, если сервер WWW способен подключать пользователей по именам.

Спецификация CGI

CGI определяет 4 информационных потока.

  1. Переменные окружения
  2. Стандартный входной поток
  3. Стандартный выходной поток
  4. Командная строка

Рисунок 4-2. CGI-интерфейс.

Переменные окружения

Переменные окружения условно делятся на два типа:

  • общие для всех типов запросов (устанавливаются для всех типов)
  • зависящие от метода запроса

К переменным первого типа относятся следующие переменные:

SERVER_SOFTWARE содержит информацию о WWW сервере (название/версия)

SERVER_NAME содержит информацию об имени машины, на которой запущен WWW сервер, символическое имя или IP адрес соответствующие URL.

GATEWAY_INERFACE содержит информацию о версии CGI(CGI/версия)

Следующие переменные являются специфичными для разных типов запросов и значения этим переменным присваиваются перед вызовом cgi-модуля.

CONTENT_LENGTH значение этой переменной соответствует длине стандартного входного потока в символах.

CONTENT_TYPE эта переменная специфицирована для запросов содержащих дополнительную информацию, таких как HTTP POST и PUT, и содержит тип данных этой информации.

SERVER_PROTOCOL эта переменная содержит информацию об имени и версии информационного протокола (протокол/версия).

SERVER_PORT значение переменной содержит номер порта, на который был послан запрос.

REQUEST_METHOD метод запроса, который был использован «POST»,»GET»,»HEAD» и т.д.

PATH_INFO значение переменной содержит полученный от клиента виртуальный путь до cgi-модуля

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

SCRIPT_NAME виртуальный путь к исполняемому модулю, используемый для получения URL.

QUERY_STRING значение этой переменной соответствует строке символов следующей за знаком «?» в URL соответствующему данному запросу. Эта информация не декодируется сервером.

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

REMOTE_ADDRESSсодержит IP адрес клиента

AUTH_TYPE если WWW-сервер поддерживает аутентификацию (подтверждение подлинности) пользователей и cgi-модуль является защищенным от постороннего доступа то, значение переменной специфицирует метод аутотентификации.

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

REMOTE_IDENT содержит имя пользователя, полученное от сервера (если сервер поддерживает аутентификацию согласно RFC 931)

HTTP_ACCEPT список типов MIME известных клиенту. Каждый тип в списке должен быть отделен запятой согласно спецификации HTTP (тип/подтип,тип/подтип и т.д.)

HTTP_USER_AGENT название программы просмотра которую использует клиент при посылке запроса.

Стандартный вывод

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

Заголовок выходного потока
В некоторых случаях необходимо избегать обработки сервером вывода cgi-модуля, и посылать клиенту данные без изменений. Для отличия таких cgi-модулей, CGI требует, чтобы их имена начинались на nph-. В этом случае формирование синтаксически правильного ответа клиенту cgi-модуль берет на себя.

Заголовки с синтаксическим разбором
Вывод cgi-модуля должен начинаться с заголовка содержащего определенные строки и завершаться двумя символами CR(0x10).

Любые строки не являющиеся директивами сервера, посылаются непосредственно клиенту. На данный момент, CGI спецификация определяет три директивы сервера:

Content-type
MIME или тип возвращаемого документа

Например: Content-type: text/html сообщает серверу, что следующие за этим сообщением данные — есть документ в формате HTML

Location
указывает серверу, что возвращается не сам документ, а ссылка на него

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

Например: Location: http://host/file.txt приведет к тому, что WWW сервер выдаст file.txt, как если бы он был затребован клиентом. Если cgi-модуль возвращает ссылки на gopher сервер, например на gopher://gopher.ncsa.uiuc.edu/. Вывод будет следующий:

*Status
задает серверу HTTP/1.0 строку-статус, которая будет послана клиенту в формате: nnn xxxxx

где: nnn — 3-х цифровой код статуса

ххххх — строка причины

Например: HTTP/1.0 200 OK


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

Стандартный входной поток

В случае метода запроса POST данные передаются как содержимое HTTP запроса. И будут посланы в стандартный входной поток.

Данные передаются cgi-модулю в следующей форме:

name=value&name1=value1&. &nameN=valueN
где name — имя переменной,
value — значение переменной,
N — количество переменных

На файловый дескриптор стандартного потока ввода посылается CONTENT_LENGTH байт. Так же сервер передает cgi-модулю CONTENT_TYPE (тип данных). Сервер не посылает символ конца файла после передачи CONTENT_LENGTH байт данных или после того, как cgi-модуль их прочитает. Переменные окружения CONTENT_LENGTH и CONTENT_TYPE устанавливаются в тот момент, когда сервер выполняет cgi-модуль. Таким образом, если в результате исполнения формы с аргументом тега 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

4.2.4 Аргументы командной строки

СGI-модуль в командной строке от сервера получает:

  • остаток URL после имени cgi-модуля в качестве первого параметра (первый параметр будет пуст, если присутствовало только имя cgi-модуля), и
  • список ключевых слов в качестве остатка командной строки для скрипта поиска, или
  • чередующиеся имена полей формы с добавленным знаком равенства и соответствующих значений переменных.

Ключевые слова, имена и значения полей формы передаются декодированными (из HTTP URL формата кодирования) и перекодированными в соответствии с правилами кодирования Bourne shell так, что cgi-модуль в командной строке получит информацию без необходимости осуществлять дополнительные преобразования.

НОВОСТИ ФОРУМА
Рыцари теории эфира
01.10.2020 — 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]69vJGqDENq4[/Youtube][/center]
[center]14:36[/center]
Osievskii Global News
29 сент. Отправлено 05:20, 01.10.2020 г.’ target=_top>Просвещение от Вячеслава Осиевского — Карим_Хайдаров.
30.09.2020 — 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Ok]376309070[/Ok][/center]
[center]11:03[/center] Отправлено 12:51, 30.09.2020 г.’ target=_top>Просвещение от Дэйвида Дюка — Карим_Хайдаров.
30.09.2020 — 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]VVQv1EzDTtY[/Youtube][/center]
[center]10:43[/center]

интервью Раввина Борода https://cursorinfo.co.il/all-news/rav.
мой телеграмм https://t.me/peshekhonovandrei
мой твиттер https://twitter.com/Andrey54708595
мой инстаграм https://www.instagram.com/andreipeshekhonow/

[b]Мой комментарий:
Андрей спрашивает: Краснодарская синагога — это что, военный объект?
— Да, военный, потому что имеет разрешение от Росатома на манипуляции с радиоактивными веществами, а также иными веществами, опасными в отношении массового поражения. Именно это было выявлено группой краснодарцев во главе с Мариной Мелиховой.

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

CGI — Common Gateway Interface

Скрипты CGI

Для того, чтобы Web-узлы были действительно интерактивными, она должны обмениваться информацией с пользователем, а не только позволять ему загружать документы. Используя программы Common Gateway Interface ( называемые CGI-скриптами ), можно создавать Web-страницы, управляемые данными. Как вы узнаете, используя скрипты CGI, узел может получать запросы и отвечать пользователю.

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

Почему Web-узлы используют CGI

Для создания динамических файлов HTML нет необходимости в применении CGI-скриптов. Однако без таких скриптов всякий раз, когда понадобится новая интерактивная динамическая страница Web, придется модифицировать программу-сервер. Спустя какое-то время программа-сервер может стать исключительно большой. Для того чтобы исключить такую модификацию сервера, разработчики используют CGI. Используя CGI-скрипты, сервер может переложить задачу создания линамических Web-документов на прикладную программу, созданную для этих специфических потребностей. Вы будете создавать вашу прикладную программу, используя C/C++, Perl, JavaScript, VBScript, или какой-либо другой язык программирования.

Программа-сервер должна вызвать CGI-скрипт

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

Броузер, сервер и CGI

Как известно, для получения броузером HTML-документов, он сначала устанавливает контакт с сервером, затем запрашивает документ ( обычно ваш броузер определяет GET-метод HTTP для получения информации от сервера ). Далее, если документ существует, сервер отвечает броузеру, посылая ему HTML-документ, и затем закрывает соединение. Применение CGI-скриптов вносит изменения в этот процесс только на стороне сервера. Броузер не знает, что сервер вызывает CGI-скрипт, и он не заботится о том, каким именно способом поступают к нему данные от сервера. Как Web-программист, при написании CGI-скриптов вы заботитесь только о входах и выходах сервера. Броузер будет устанавливать контакт с программой сервера, которая, в свою очередь, исполняет CGI-скрипт. Ваш скрипт, в свою очередь, выполняет необходимую обработку данных, чтобы сформатировать требуемый выход. Обычно ваш сервер передает выходные данные из скрипта в форме HTML-броузеру. Чтобы выполнить это, верверная программа добавляет необходимую заголовочную информацию к выходным данным, сформированным скриптом, и посылает эту заголовочную информацию вместе с данными обратно броузеру. Затем сервер закрывает соединение и ждет новых запросов.

Как вы, возможно, знаете, серверы, которые работают под 32-битными операционными системами, такими как Windows 95/98 или Windows NT, могут обрабатывать запросы от многих пользователей одновременно. Отсюда следуте, что несколько пользователей могут одновременно использовать скрипт. Поэтому каждый из них, в зависимости от запроса, будет видетьь свою картину ответа сервера.

Взаимосвязь сервера и CGI-скрипта

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

Как вы уже знаете, HTTP является протоколом, с помощью которого клиенты и серверы Web обеспечиваются информацией. Заголовочная HTTP информация помогает программам эффективно выполнять обмен данными. Поэтому необходимо уделить особое внимание заголовочной информации, которой сервер снабжает броузер. Например, когда программа-сервер готова послать данные броузеру, она посылает заголовки, описывающие статус данных, тип данных и т.д. В свою очередь броузер использует заголовок ( Content-type ) для подготовки к выводу данных на экран. Сервер отвечает за то, чтобы обеспечить этой метаинформацией броузер каждый раз, когда он посылает ему данные.

CGI т базы данных

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

Где находятся скрипты

Стандарты CGI не предписывают, куда должны помещаться скрипты, то есть не определяют заранее диск и каталог. Обычно Web-сервер ожидает найти скрипты в каталоге /CGI-BIN, который расположен нажи каталога самой программы сервера. Если вы помещаете свои скрипты на чей-то сервер, необходимо определить каталог для своих файлов, содержащих скрипты.

Расширение имен файлов CGI-скриптов

Серверы HTTP для Windows-систем обычно для CGI-файлов используют расшерение EXE или PL. Например, если вы создаете CGI-программу ( скрипт ), используя язык программирования С, то расширение ваших файлов-скриптов будет, вероятно, ЕХЕ. Аналогично, если вы создаете скрипт с помощью языка Perl, расширение ваших файлов будет PL.

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

Основы взаимодействия между Web-сервером и CGI-скриптом

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

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

Переменные окружения

Переменная AUTH_TYPE


Скрипты CGI используют переменную окружения AUTH_TYPE для идентификации пользователя, который пытается получить доступ к скрипту. Если сервер сконфигурирован так, чтобы поддерживать идентификацию пользователя, то пользователь, пытающийся получить доступ к скрипту, должен назвать свое имя и пароль. Например, следующее значение переменной означет, что от пользователя требуется основной уровень идентификации:

Переменная CONTENT_LENGTH

Скрипты используют переменную окружения CONTENT_LENGTH для того, чтобы определить точное число байт, содержащихся в просоединенных данных. Например, если запрос содержит документ длиной в 1,024 байта, то переменной окружения присваивается следующее значение:

Переменная CONTENT_TYPE

Скрипты используют эту переменную окружения для запросов, которые содержат присоединенную информацию. К такому типу запросов отоносится HTTP-операция POST. Содержащаяся в переменной информация указывает на тип присоединенных данных ( MIME-тип.подтип). Например, если запрос содержит присоединенный документ HTML , то переменная окружения будет принимать следующие значения:

Переменная GATEWAY_INTERFACE

Скрипты используют эту переменную для того, чтобы определить версию, номер выпуска спецификации CGI, которой удовлетворяет Web-сервер. Формат номера выпуска спецификации следующий: CGI/номер выпуска. Например, для CGI выпуска 1.1 переменная окружения будет иметь следующий вид:

Переменная PATH_INFO

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

Путь записывается в относительной форме, где за базу берется корневой каталог сервера. Иными словами, корневой каталог сервера является базисом для относительного пути, который и присваивается переменной PATH_INFO. Например, если задан путь c:/cgi-bin/example1.exe/sports.html, то переменная окружения будет иметь следующий вид:

Переменная PATH_TRANSLATED

Скрипты используют эту переменную для получения окончательной, пригодной для непосредственного использования информации относительно пути. Сервер переводит информацию переменной путем выполнения необходимых преобразований пути. Например, если переменная PATH_TRANSLATED имеет значение /sports.html, а корневым дирикторием сервера служит c:\, то переменная окружения будет иметь следующее значение:

Переменная QUERY_STIRNG

Скрипты используют эту переменную для того, чтобы получить информацию в текстовой форме ( состоящую из аргументов ), которая следует справа от знака вопроса после URL, переданного от пользователя скрипту для обработки. Эта текстовая сторока содежит вход для скрипта. Далее сервер заменяет в данном тексте каждый пробел на знак » + «, а все непечатные символы знаком » %dd», где d является базой десятичной системы счисления.

Скрипт должен содержать код для расшифровки этой текстовой строки. Сервер, передавая эту информацию скрипту, не должен заниматься декодированием информации запроса каким-либо образом. Сервер должен также установить переменную QUERY_STRING в случае, если пользователь обеспечивает какую-то информацию запроса. Например, для URL http://www.jamsa.com/cgi-bin/grandma.exe?name=margaret+alarcon переменная окружения имеет значением следующую величину:

Переменная REMOTE_ADDR

Скрипты используют эту переменную для получения IP-адресса удаленного узла ( броузера ), который делает запрос. Например, значение переменной окружения может быть следующим:

Переменная REMOTE_HOST

Скрипты используют эту переменную для того, чтобы получить имя узла, с которого делается запрос. Если сервер не знает имя узла, делающего запрос, то сервер должен присвоить значение переменной окружения REMOTE_ADDR и не присваивать значения переменной REMOTE_HOST . Напрмиер, для узла jamsa.com переменная окружения будет содержать следующее значение:

Переменная REMOTE_IDENT

Используется для того, чтобы получиь имя удаленного пользователя, делающего запрос к серверу. Программа Web-сервера представляет собой программное обеспечение. вызывающее ваш скрипт. Если HTTP Web-сервер поддерживает протокол RFS 931 (Authentication Server Protocol), то сервер установит эту переменную равной значению имени пользователя, которое имеется у сервера. Скрипты могут использовать эту переменную только для регестрации пользователя. Напрмер, если имя удаленного пользователя pschmauder и он назодится на удаленном узле jamsa.com , то переменная примет следующее значение:

Переменная REMOTE_USER

Используется для того, чтобы получить имя удаленного пользователя без имени узла, с которого он производит запрос. Если сервер поддерживает идентификацию пользователя и скрипт является защищенным, то сервер установит имя пользователя и присвоит его этой переменной. Например, предположим, что именем удаленного пользователя является pschmauder . Тогда переменная будет выглядеть следующим образом:

Переменная REQUEST_METHOD

Используется для того, чтобы определить тип HTTP-запроса, который послан броузером серверу и служит для вызова скриптов. Эта переменная может принимать значения GET, HEAD или POST. Например, если броузер посылает GET-метод, то переменная окружения содержит следующее:

Переменная SCRIPT_NAME

Используется для того, чтобы определить виртуальный путь к скрипту, который будет запущен сервером. Например, если имеется URL http://www.jamsa.com/cgi-bin/someprog.exe, то переменная окружения примет следующее значение:

Переменная SERVER_NAME

Использутся для того, чтобы определитьимя домена ли IP-адрес комрьютера, на котором раположен Web-сервер. Например, когда сервер возвращает IP-адрес, переменная окружения будет иметь вид, подобный следующему:

Переменная SERVER_PORT

Используется для того, чтобы определить номер порта, который пользователь (броузер) использует для связи с Web-сервером. Если используется HTTP-порт по умолчанию, то эта величина равна 80. Если используется какой-то другой порт, например, http://www.jamsa.com:3000, то переменная принимает следующее значение:

Переменная SERVER_PROTOCOL

Используется для того, чтобы определить имя и номер выпуска протокола, используемогоклиентом (броузером) для того, чтобы послать запрос к Web-серверу. Анализируя содержание переменной, скрипт может идентифицировать имя и номер выпуска протокола, который он должен использовать при передаче данных серверу. Формат имени протокола и номера выпуска следующий: протокол/номер выпуска. Например, для HTTP 1.1 переменная окружения будет иметь следующий вид:

Переменная SERVER_SOFTWARE

Как вы знаете, Web-сервер исполняет скрипты CGI. Поскольку скрипт может испольняться по-разному для различных серверных программ, скрипты используют эту переменную для того, чтобы определить имя программы Web-сервера и ее номер версии. Формат имени Web-сервера и номер версии должен передаваться CGI следующим образом: имя/версия. Например, для FOLK WEB — сервера версии 1.01 переменная окружения будет иметь седующий вид:

Дополнительные переменные окружения

В дополнение к переменным окружения. обсуждавшимся ранее, сервер также помещает данные из заголовка запроса, полученного от клиента, в переменные окружения. Сервер присваивает значения переменным, чьи имена начинаются с префикса HTTP_, после которого идет имя заголовка. Сервер заменяет все символы переноса (-) в заголовке на (_). Сервер может также исключать любые заголовки, которые он уже обработал, используя переменные окружения, такие как AUTH_TYPE, CONTENT_TYPE и CONTENT_LENGTH.

Переменная HTTP_ACCEPT

Используется для того, чтобы определить, какие MIME-типы может принимать броузер. Они определены в HTTP-заголовках, которые броузер послал серверу. Как известно, MIME-тип задается в виде тип/расширение. Если имеется насколько MIME-типов, то они разделяются запятыми. Например, переменная окружения может принимать следующее значение:

Переменная HTTP_USER_AGENT

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

Опции командной строки CGI

Обычно CGI-скрипты используют командную строку в качестве входа для того, чтобы выполнить запрос ISINDEX, позволяющий добавить интерактивный поиск по ключевому слову к вашему HTML-документы. Однако не все серверные программы поддерживают ISINDEX-запрос. Броузер посылает запрос в виду командкной строки серверу. Программа сервера может идентифицировать входную командную строку, устанавливая, использовал ли броузер GET-метод HTTP и содержит ли строка URL символы uuencoded =.

Если броузер использует GET-метод HTTP и строка URL-поиска не содержит символы uuencoded =, то запрос осуществляется в форме командной строки. Перед тем как сервер вызовет соответствующий скрипт, серверная программа должна расщепить командную строку, используя знак (+), для отделения параметров. Затем сервер выполняет дополнительное декодирование ( если необходимо ) каждого параметра, переданного в URL-строке поиска, и хранит каждый параметр-строку в массиве, названную argv.

Дополнительное декодирование, выполняемое сервером, состоит в разделении отдельных строк, используя амперсанда (&) в качестве разделителя. Далее сервер расщепляет каждую из этих строк снова, используя знак (=) для того, чтобы отделить имя переменной, которое ставиться слева от знака (=), от значения переменной, которое стоит справа от (=). Сервер хранит число элементов, содержащихся в массиве argv, в переменной целого типа argс.

Если сервер нашел знак равенства внутри строки QUERY_STRING переменной окружения, то он не будет посылать командную строку в качестве входа в скрипт. Также если по какой-то причине программа сервера не может послать массив argv скрипту, она обеспечит недекодированную информацию запроса в переменной окружения QUERY_STRING.

Стандартный ввод ( STDIN )

Когда броузер запрашивает сервер ( например, используя HTTP-метод POST ), информация, которую получает скрипт, приходит со стандартного дескриптора ввода stdin. Серверная программа посылает скрипту переменную окружения CONTENT_LENGTH. Эта переменная содержит число байт, которое сервер посылает скрипту через этот дескриптор. Скрипт может использовать значение переменной CONTENT_LENGTH для того, чтобы определить, сколько данных должно поступить со стандартного ввода. Сервер также снабжает скрипт переменной окружения CONTENT_TYPE, которая помогает скрипту определить, как обрабатывать получаемые данные. В конце этого потока данных сервер может послать ( а может и не посылать ) маркер конца файла. Однако именно скрипт обязан определить, какой объем данных читать, и использует он для этого переменную окружения CONTENT_LENGTH.

Например, если форму использует HTTP-метод POST (

Perl для CGI / Введение

Предисловие


Программирование на Perl в простом компьютере (без серверного приложения) подобно написанию сценария для кинофильма. Вы можете написать прекрасный сюжет, даже шедевр, можете вложить туда всю свою душу и фантазию, но примут-ли этот сценарий на киностудии? Поймут-ли Вас, или понесете-ли вы туда его вообще? Вот так и программирование в среде CGI. Вы пишете программу в обычном текстовом редакторе без всякой поддержки со стороны транслятора и можете написать все что угодно. Вот только поймет-ли Вашу программу потом серверный Perl-интерпретатор? Не нужно боятся. Все CGI-программы этого сайта (ПерЧАТка, Барахолка, СКОБа, Почтовый робот, Каталог и другие) написаны именно на локальном компьютере, а отлаживались уже потом на сервере через простое dial-up соединение. Так что нет ничего невозможного. Если Вам что-то будет непонятно, или захочется что-то добавить, или просто возникнут вопросы, обращайтесь в соответствующий раздел форума, возможно там уже есть ответ на Ваш вопрос, а если нет, то думаю это самый быстрый способ его получить. Однако есть довольно простой способ облегчить себе жизнь. Если Вы работаете под управлением ОС Windows, то можете скачать Small HTTP Server (100Кб) для эмуляции HTTP-соединения (для этого нужно создать виртуальные хосты с привязкой к системному хосту (127.0.0.1), или вручную добавить в файл C:\Windows\system32\drivers\etc\hosts строки типа: 127.0.0.1 www.myhost.zone) и ActivePerl 5.6.1 (8645Кб). Так можно легко отлаживать Perl-программы, не выходя в интернет.

Дальнейший текст (кроме раздела MySQL, написанного С.А.Семищенко) написан автором, данные которого вы найдете ниже, с небольшими нашими дополнениями и исправлениями, под нашей редакцией. В первоисточнике он назывался: «Учебное пособие по CGI-программированию от Леши».

Пару слов от автора

Что меня заставило взятся за этот нелегкий труд написания данного учебного пособия. Ну во первых то что практически НЕТ ничего по CGI-програмированию на русском языке, а большинству тех, кто хотел бы изучить CGI, документация на английском в отличии от тех немногих, типа меня, практически недоступна для понимания. Чтобы помочь им преодолеть этот, в первую очередь языковый, барьер я и сел писать эту книгу.

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

Если также у вас есть какие-то вопросы -тоже пишите, я с радостью постараюсь ответить на них.

Краткое лирическое отступление насчет CGI

Итак что такое CGI-скрипты и вообще подобные вещи. Начнем с того что ваш браузер (когда вы набрали URL) соединяется по протоколу HTTP с указаным сервером и просит у него нужный файл, примерно так:

Вот это самое главное в запросе. Ну тут дальше идет посылаемая браузером информация о себе и о том что более подробно ему надо (например Accept: */*). Ну и если запрошен простой файл например .html то если такой файл есть, сервер отошлет браузеру ответ:

HTTP/1.0 200 Okay
Content-Type: text/html

В ответе, состоящем из заголовка и тела, в заголовке содержится код возврата и информация о типе содержимого. Далее после пустой строки (она нужна чтоб отделить заголовок от тела) идет информация из самого документа , по заданому URL .

Вот в принципе и весь WWW. Ходишь от ссылки к ссылке.

А что если Нужно внести в этот унылый процесс что-нибудь по настоящему интерактивное, динамическое, прекрасное и великолепное? Что-ж есть ответ и на этот вопрос. Просто если в запрашиваемом URL указать специальную программу (CGI, программа Common Gateway Inteface - Общего Шлюзового Интерфейса) и то что эта прога выдаст то и отправиться браузеру. Сервер запускает .cgi программу и она например обработав данные формы заносит вас куда-нибудь в свою базу данных, а вам сообщит что вы большой молодец 🙂
Ну надеюсь я вас заинтриговал?

Введение

Краткие сведения о том что надо знать чтоб писать CGI скрипты:

Ну во-первых надо знать что такое интернет и как он работает (а вы знаете? ;))) ). А так-же чуть-чуть умения програмировать (это самое главное).

На кого ориентировано данное учебное пособие -спросите вы? Ну в принципе на достаточно широкую аудиторию тех, кто занимается Интернет-программированием и кто хотел бы освоить премудрости интерфейса CGI. Данная книга будет весьма полезна для web-дизайнеров, системных администраторов интернет-серверов, программистов и для простых пользователей интернет, которые хотели бы сделать свой сайт по-настоящему достойным называться хорошим сайтом.

Так как интернет в основном строится на операционной системе UNIX , то изложеный здесь материал может быть без особых модификаций реализован на практически любой UNIX-системе. Кроме того, я также делаю предположение, что ваш web-сервер поддерживает интерфейс CGI и для вас эта поддержка включена. (на "халявных" серверах администраторы отключают CGI и SSI для пользовательских директорий - просто это такая политика - предоставлять только ОЧЕНЬ МИНИМАЛЬНЫЙ сервис. Правда в настоящее время появилось достаточно много бесплатных хостингов поддерживающих CGI и SSI, некоторые из них можно найти в лоцмане). Так что если вы хотите изучать CGI то вам нужет нормальный, полнофункциональный хостинг (или собственный сервер (см.начало статьи). Если же вы сами являетесь системным администратором на своем сервере, то для вас, естественно нет проблем, ведь включить CGI для какой-нибудь директории - это просто подправить одну строчку в файле конфигурации сервера.

Замечание: Если вы используете Windows NT, то материал данной книги вам будет тоже очень полезен, однако будьте готовы к тому что в некоторые скрипты придется вносить значительные изменения. В некоторых случаях, когда сказывается то, что возможности NT по работе с сетью намного хуже чем у UNIX, некоторые скрипты вовсе нельзя будет использовать.

Давайте вместе писанем какой нибудь простенький скриптик а потом я вам расскажу где здесь собака порылась. Ну сначала в своем домашнем каталоге создайте директорию cgi-bin:

cd public_html
mkdir cgi-bin
chmod 0777 cgi-bin

Последняя строчка будет очень важна. Далее возьмите текстовый редактор и наберите:

#!/usr/bin/perl
#first.cgi
print "Content-Type: text/html\n\n";
print " ";
print "

Hello you.

Сохраните его в директории cgi-bin под именем first.cgi . Ну как сохранили? А теперь сделайте его исполняемым (ведь это программа):

chmod +x first.cgi

Ну вот, подходим к торжественному моменту. наберите в строке браузера http://www.ваш.сервер.ru/

ваш_логин/cgi-bin/first.cgi
и посмотрите что будет. Будет одно из двух: либо скрипт заработает и вы увидите сгенерированую им страничку (поздравляю, в нашем полку прибыло!) либо Internal Server Error 500 -тогда не расстраивайтесь, вы что-то сделали не так. Тогда Вам пригодится пособие по ловле блох. Ну во-первых проверку синтаксиса можно осуществить следующим образом:

Perl вам сразу выдаст либо сообщения об ошибках (ну бывает, точку с запятой пропустили, скобочки или кавычки забыли закрыть) это сразу по ходу дела поправимо. Более грубая с логической точки зрения это пропустить вывод пустой строки, которая отделяет заголовок от тела:

print "Content-Type: text/html\n\n"; #Все Правильно
print "Content-Type: text/html\n"; #ОШИБКА.

Еще распространенная ошибка: в каком редакторе писали программу? В Windows Notepad или WordPad (Write)? Все правильно, только после сохранения вам надо заменить все Windows-символы перевода строки на Unix-символы. Дело в том, что в Windows перевод строки осуществляется сразу двумя символами, CrLf (коды 13 и 10 (\c\n)), а в Unix только Lf (10 (\n)). Perl будет интерпретировать до первого символа возврата каретки Cr, а дальше считывать программу не будет. Но преобразовать текст в Unix-формат очень просто, например при помощи FAR-менеджера. Открываете файл для редактирования по F4, далее нажимаете Сохранить как (Shift+F2) и указываете как Unix-текст. Ну и конечно после закачки на сервер нужно чтобы у Perl-программы были атрибуты 755. Кстати Perl-скрипты могут иметь расширение не только .cgi, но и .pl .

Разберем скрипт:
Первая строка #!/usr/bin/perl Просто указывает где в системе расположен компилятор Perl. Обычно он находится /usr/bin/perl или /usr/local/bin/perl, выяснить это можно одной из комманд which perl или whereis perl ну или (что очень долго) запустить полный поиск find / -name perl -print. Вторая строка это просто коментарий -вы можете тыкать что угодно после знака #, однако я пишу обычно во второй строке название скрипта, что очень удобно. Затем идет print "Content-Type: text/html\n\n"; Это заголовок указывающий тип содержимого. Все что скрипт печатает в свой стандартный вывод STDOUT идет на обработку к серверу. Пустая строка отделяет заголовок от тела, которое в нашем случае представляет собой:

Hello you.

Сервер обработает ответ скрипта и на базе него сформирует и пошлет браузеру ответ. Сервер обычно не изменяет тела сообщения, он только дополняет заголовок нужными для работы протокола HTTP полями.

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

Переменные среды CGI

Предыдущий скрипт не содержал ничего особенно замечательного, так просто вываливал HTMLый текст который благополучно и отбражался на экране браузера. Но настоящую мощь CGI придает возможность обработки параметров, которые переданы скрипту. Например вы можете набрать: http://www.somehost.ru/somedir/cgi-bin/my_cgi.cgi?param=value, то есть вы хотите чтоб скрипт my_cgi.cgi обработал для вас параметер param со значением value (ну это например) или когда вы заполнили запрос в форме (например yahoo или altavista). Это с точки зрения пользователя. А на сервере при запуске CGI-скрипта сервер формирует среду окружения в которой скрипт может найти всю доступную информацию о HTTP-соединении и о запросе. Вот эти переменные:

  • REQUEST_METHOD - Это одно из самых главных полей используемое для определения метода запроса HTTP. Протокол HTTP использует методы GET и POST для запроса к серверу. Они отличаются тем что при методе GET запрос является как-бы частью URL т.е. http://www. /myscript.cgi?request, а при методе POST данные передаются в теле HTTP-запроса (при GET тело запроса пусто) и следовательно для CGI тоже есть различие. При GET запрос идет в переменную QUERY_STRING (на самом деле в $ENV<'QUERY_STRING'>, но пока это опустим для удобства описания), а при POST подается на STDIN скрипта. Пример: REQUEST_METHOD=GET
  • QUERY_STRING - Это строка запроса при методе GET. Вам всем известно что запрос из формы кодируется браузером поскольку не все символы разрешены в URL некоторые имеют специальное назначение. Теперь о методе urlencode: неплохо бы чисто формально напомнить, что все пробелы заменяются в URL на знак '+', а все специальные и непечатные символы на последовательность %hh, где hh-шестнадцатиричный код символа, разделитель полей формы знак '&'. Так что при обработке форм надо произвести декодирование. Пример: QUERY_STRING= name=quake+doomer&age=20&hobby=games
  • CONTENT_LENGTH - длина в байтах тела запроса. При методе запроса POST необходимо считать со стандартного входа STDIN CONTENT_LENGTH байт, а потом производить их обработку. Обычно методом POST пользуются для передачи форм, содержащих потенциально большие области ввода текста TEXTAREA. При этом методе нет никаких ограничений, а при методе GET существуют ограничения на длину URL . Пример: CONTENT_LENGTH=31
  • CONTENT_TYPE - тип тела запроса (для форм кодированых выше указаным образом он application/x-www-form-urlencoded).
  • GATEWAY_INTERFACE - версия протокола CGI. Пример: GATEWAY_INTERFACE=CGI/1.1
  • REMOTE_ADDR - IP-Адрес удаленого хоста, делающего данный запрос. Пример: REMOTE_ADDR=139.142.24.157
  • REMOTE_HOST - Если запрашивающий хост имеет доменное имя, то эта переменная содержит его, в противном случае -тот же самый IP-адрес что и REMOTE_ADDR. Пример: REMOTE_HOST=idsoftware.com

SCRIPT_NAME - Имя скрипта, использованное в запросе. Для получения реального пути на сервере используйте SCRIPT_FILENAME. Пример: SCRIPT_NAME=/

paaa/guestbook.cgi

  • SCRIPT_FILENAME - Имя файла скрипта на сервере. Пример: SCRIPT_FILENAME=/home/p/paaa/public_html/cgi-bin/guestbook.cgi
  • SERVER_NAME - Имя сервера, чаще всего доменное как www.microsoft.com, но в редких случаях за неимением такового может быть DNS-адресом как 157.151.74.254 Пример: SERVER_NAME=www.uic.nnov.ru
  • SERVER_PORT - TCP-Порт сервера используюшийся для соединения. По умолчаниию HTTP-порт 80, хотя может быть в некоторых случаях другим. Пример: SERVER_PORT=80
  • SERVER_PROTOCOL - Версия протокола сервера. Пример: SERVER_PROTOCOL=HTTP/1.1
  • SERVER_SOFTWARE - Програмное обеспечение сервера. Пример: Apache/1.0
  • AUTH_TYPE, REMOTE_USER - Эти переменные определены в том случае, когда запрошеный ресурс требует аутентификации пользователя.
  • Переменные заголовка HTTP-запроса.


    За исключением тех строк из заголовка HTTP-запроса которые были включены в другие переменные, сервер приделывает строкам префикс HTTP_ и заменяет знаки '-' на '_':

    • HTTP_ACCEPT - Давая запрос на сервер браузер обычно расчитывает получить информацию определеного формата, и для этого он в заголовке запроса указывает поле Accept:. Отсюда скрипту поступает cписок тех MIME, которые браузер готов принять в качестве ответа от сервера. Пример: HTTP_ACCEPT=text/html,text/plain,image/gif
    • HTTP_USER_AGENT - Браузер обычно посылает на сервер и информацию о себе, чтобы базируясь на знании особеностей и недостатков конкретных браузеров CGI-скрипт мог выдать информацию с учетом этого. Например, разные браузеры могут поддерживать или не поддерживать какие-то HTML-тэги. Пример: HTTP_USER_AGENT=Mozila/2.01 Gold(Win95;I)
    • HTTP_HOST - Имя хоста к которому обращается браузер. Так как физически на одном сервере может находиться сразу много серверов (Виртуальные Хосты), то должен быть способ сообщить серверу к какому именно идет обращение. Скрипт же может тоже в зависимости от этой переменной производить различные действия, например если он используется на сайтах сразу нескольких виртуальных хостов. Пример: HTTP_HOST=www.nnov.city.ru

    Ну,начнем применять на практике усвоеные уроки:

    sub urldecode < #очень полезная функция декодирования
    local($val)=@_; #запроса,будет почти в каждой вашей CGI-программе
    $val=

    print "Content-Type: text/html\n\n";
    print " CGI-Variables \n";
    print " \n";
    print "Enter here something:
    \n";
    print "Your request is:$ENV<'REQUEST_STRING'>
    \n";
    print "Decoded request is:urldecode($ENV<'REQUEST_STRING'>)
    \n";
    print " \n";
    print "Variables:
    \n";
    print " REQUEST_METHOD =$ENV<'REQUEST_METHOD'>
    \n";
    print " QUERY_STRING =$ENV<'QUERY_STRING'>
    \n";
    print " CONTENT_LENGTH =$ENV<'CONTENT_LENGTH'>
    \n";
    print " CONTENT_TYPE =$ENV<'CONTENT_TYPE'>
    \n";
    print " GATEWAY_INTERFACE =$ENV<'GATEWAY_INTERFACE'>
    \n";
    print " REMOTE_ADDR =$ENV<'REMOTE_ADDR'>
    \n";
    print " REMOTE_HOST =$ENV<'REMOTE_HOST'>
    \n";
    print " SCRIPT_NAME =$ENV<'SCRIPT_NAME'>
    \n";
    print " SCRIPT_FILENAME =$ENV<'SCRIPT_FILENAME'>
    \n";
    print " SERVER_NAME =$ENV<'SERVER_NAME'>
    \n";
    print " SERVER_PORT =$ENV<'SERVER_PORT'>
    \n";
    print " SERVER_PROTOCOL =$ENV<'SERVER_PROTOCOL'>
    \n";
    print " SERVER_SOFTWARE =$ENV<'SERVER_SOFTWARE'>
    \n";
    print " HTTP_ACCEPT =$ENV<'HTTP_ACCEPT'>
    \n";
    print " HTTP_USER_AGENT =$ENV<'HTTP_USER_AGENT'>
    \n";
    print " HTTP_HOST =$ENV<'HTTP_HOST'>
    \n";
    print " \n";
    print "All enviroment:
    \n";
    foreach $env_var (keys %ENV) <
    print " $env_var=$ENV <$env_var>
    \n";
    >

    Эта программа выдаст в ваш броузер значения всех системных переменных Perl.

    Так как все ваши .cgi -файлы должны быть исполняемыми то чтоб облегчить себе жизнь заведите себе в директории cgi-bin командный файл mkcgi, содержащий:

    и сделайте его в свою очередь исполняемым chmod +x mkcgi -он сильно упростит вам жизнь.

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

    Если до сих пор не поняли каким образом обрабатывать запросы HTTP при помощи Perl, то рассмотрим следующий пример:

    #Config part
    #query.pm

    if ($ENV <'REQUEST_METHOD'>eq "GET") < # Если REQUEST_METHOD=GET
    $qs = $ENV<'QUERY_STRING'>; # то присваиваем переменной $qs строку запроса QUERY_STRING
    > elsif ($ENV <'REQUEST_METHOD'>eq "POST") < # иначе если REQUEST_METHOD=POST
    read(STDIN, $qs, $ENV<'CONTENT_LENGTH'>); # то считываем в $qs значение STDIN, длиной CONTENT_LENGTH
    >

    my @split = split (/&/, $qs); # в локальный (my) массив @split считываем значения
    foreach $split (@split) < # разделенные ампресандом (&)
    ($query_key, $query_value) = split (/=/, $split);
    $query_value =

    1; # завершаем модуль с кодом ошибки - 1 (все OK)

    Напишите все это и сохраните в файле query.pm, сделав его доступным для чтения и записи (chmod 777). Это не обычная CGI-программа, а оверлейный модуль (PM-Perl Module). Он не исполняется самостоятельно, но может вызываться из CGI-скрипта строкой: require Name_module;. Такое построение программы оправдано когда в pm-модуле содержаться процедуры, необходимые в большинстве процедур, а CGI-сценарий вызывает его перед выполнением. В этом-же модуле можно указать конфигурационные переменные (типа вашего e-mail, путь к данным, опции и т.п.). Только-что написанный нами модуль удобно использовать во всех своих программах, ведь любой запрос декодируется и распределяется, при помощи него, в хэш-массив %query, откуда любое поле запроса можно считать из переменных типа: $query<'Name_value_request'>. В Windows файлы .pm должны иметь то же имя, что и .cgi-программы, их вызывающие. Рассмотрим это на следующем примере:

    require query; # Запрос модуля query.pm

    &header; # вызов процедуры header из query.pm для печати стандартного заголовка
    print

    [END]
    print "Имя: $query<'name'>
    "; # Распечатать значение поля name из запроса
    print "Фамилия: $query<'fam'>";
    print

    Query Results

    • RealName = Петров Иван Сидорович
    • Sex = Мужской
    • Submit = Послать запрос

    И на экране браузера
    Query Results
    You submitted the following name/value pairs:
    RealName = Петров Иван Сидорович
    Sex = Мужской
    Submit = Послать запрос

    Ниже приведен исходный текст программы post-query.

    #include
    #ifndef NO_STDLIB_H
    #include
    #elsechar *getenv();
    #endif
    #define MAX_ENTRIES 10000

    typedef struct <
    char *name;
    char *val;
    > entry;

    char *makeword(char *line, char stop);
    char *fmakeword(FILE *f, char stop, int *len);
    char x2c(char *what);
    void unescape_url(char *url);
    void plustospace(char *str);

    main(int argc, char *argv[])

    <
    entry entries[MAX_ENTRIES];
    register int x,m=0;
    int cl;
    printf("Content-type: text/html%c%c",10,10);
    if(strcmp(getenv("REQUEST_METHOD"),"POST"))
    < printf("This script should be referenced with a METHOD of POST.\n");
    printf("If you don't understand this, see this "); printf(" forms overview.%c",10);
    exit(1);
    > if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) exit(1);
    >
    cl = atoi(getenv("CONTENT_LENGTH"));
    for(x=0;cl && (!feof(stdin));x++)
    unescape_url(entries[x].val);
    entries[x].name = makeword(entries[x].val,'=');
    >
    printf("

    Query Results

    Надо отметить, что post-query не обрабатывает имена, поэтому в примере они даны на английском языке. Если Вы используете русские названия имен, то вы должны обработать имена также как и значения, т.е. заменить все символы "+" на пробелы и преобразовать шестнадцатеричные коды кириллических символов в сам символ.
    Приведем также исходный текст функций используемых post-query

    char *makeword (char *line, char stop) <
    /* Предназначена для выделения части строки, ограниченной "стоп-символами"*/
    int x = 0,y;
    char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
    for(x=0;((line[x]) && (line[x] != stop));x++)
    word[x] = line[x];
    word[x] = '\0';
    if(line[x]) ++x;
    y=0;

    while(line[y++] = line[x++]);
    return word;
    >

    char *fmakeword (FILE *f, char stop, int *cl) <
    /* Предназначена для выделения строки, ограниченной "стоп-символом" stop, из потока f длиной cl.
    */
    int wsize;
    char *word;
    int ll;

    wsize = 102400;
    ll=0;
    word = (char *) malloc(sizeof(char) * (wsize + 1));

    while(1) <
    word[ll] = (char)fgetc(f);
    if(ll==wsize) <
    word[ll+1] = '\0';
    wsize+=102400;
    word = (char *)realloc(word,sizeof(char)*(wsize+1));
    >
    --(*cl);
    if((word[ll] == stop) || (feof(f)) || (!(*cl))) <
    if(word[ll] != stop) ll++;
    word[ll] = '\0';
    return word;
    >
    ++ll;
    >
    >

    char x2c (char *what) <
    /* Предназначена для преобразования шестнадцатиричного кода символа в код символа
    */
    register char digit;

    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
    digit *= 16;
    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
    return(digit);
    >

    void unescape_url (char *url) < register int x,y; for(x=0,y=0;url[y];++x,++y) <
    if((url[x] = url[y]) == '%') <
    url[x] = x2c(&url[y+1]);
    y+=2;
    >
    >
    url[x] = '\0';
    >

    void plustospace (char *str) <
    /*замена символов "+" на символ "пробел"*/
    register int x;

    for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
    >

    Для демонстрации реализации формы с методом запроса GET воспользуемся той же самой формой, что и для метода POST и программой query. Для этого изменим значение атрибутов ACTION и METHOD в теге FORM.

    использование: предназначен для получения информации от клиента и определяет начало и конец формы.

    атрибуты:

      Обязательные
      ACTION - определяет URI (Universal Resource Identifier-адрес или место расположения документа) CGI-скрипта
      METHOD - определяет метод передачи информации скрипту. Возможные значения GET или POST.

  • Необязательные
    [ENCTYPE] - определяет тип MIME декодирования информации (значение этого атрибута по умолчанию - "application/x-www-form-urlencoded").
    [SCRIPT] - используется для передачи URI скрипта. Язык скрипта и интерфейс пользователя при этом не являются частью спецификации HTML 3.0
  • Важно: Формы не могут быть вложенными!

    Для реализации формы используются следующие теги.

    использование: предназначен для создания различных по своей функциональности полей ввода.

    TYPE - определяет тип поля формы.

      Допустимые значения:
      TEXT - позволяет символьный ввод.
      PASSWORD - предназначено для "скрытого" ввода символов (вводимые символы не отображаются).
      CHECKBOX - поле, позволяющее два состояния ("есть", "нет"). Должен применяться с атрибутами NAME и VALUE
      RADIO - поле, позволяющее выбор "один из всех"
      SUBMIT - кнопка инициирующая передачу информации из формы обрабатывающему скрипту, определенному в ACTION в соответствии с методом, определенным атрибутом METHOD.
      RESET - кнопка, сбрасывающая все введенные ранее значения.
      IMAGE - поле позволяющее воспроизвести событие SUBMIT при помощи вашего изображения, при этом возвращается два значения: name.x = координата Х и name.y = координата Y, где Х и Y координаты положения курсора мыши на изображении в момент щелчка.
      HIDDEN - поле создающее неотображаемое значение.
      RANGE - определяет поле позволяющее ввести цифровое значение с определенными допустимыми верхним и нижним пределами.
      Используется вместе с атрибутами MAX и MIN определяющими область допустимых значений (например: TYPE=RANGE MIN=1 MAX=10).

    NAME - значение этого атрибута определяет идентификатор поля.
    VALUE - значение этого атрибута определяет что будет передано в качестве значения по умолчанию для данного поля при инициации формы.
    SRC - определяет URI файла изображения. Используется только с типом поля IMAGE.
    [CHECKED] - позволяет установить начальное значение поля типа CHECKBOX.
    SIZE - определяет размер поля.
    [MAXLENGTH] - определяет максимальное количество символов, допустимое для ввода в поле.
    [ALIGN] - позволяет позиционирование

      Допустимые значения:
    • по вертикали
      TOP - выравнивание по верху.
      MIDDLE - выравнивание по середине.
      BOTTOM выравнивание по низу.
      Эти значения используются только с TYPE=IMAGE.
    • по горизонтали
      [LEFT] - выравнивание слева
      [RIGHT] - выравнивание справа

    [DISABLED] - определяет поле как "read only" - только для чтения. Значение в поле не может быть изменено пользователем.
    [ERROR] - определяет сообщение об ошибке, объясняющее, почему введенное значение в поле не верно.

    использование: предназначен для определения области ввода текста. Размер поля определяется атрибутами.

    NAME - значение этого атрибута определяет идентификатор поля. Возвращается при инициации формы.
    ROWS - определяет количество строк в текстовой области.
    COLS - определяет количество столбцов в текстовой области.
    [VALUE] - задает значение по умолчанию.
    [DISABLED] - определяет поле как "read only" - только для чтения. Значение в поле не может быть изменено пользователем.
    [ERROR] - определяет сообщение об ошибке, объясняющее, почему введенное значение в поле не верно.

    использование: предназначен для определения области выбора из нескольких значений (меню).

    NAME - значение этого атрибута определяет идентификатор поля. Возвращается при инициации формы.
    [SIZE] - определяет количество видимых возможных значений.
    [MULTIPLE] - определяет возможность множественного выбора.
    [DISABLED] - определяет меню как "read only" - только для чтения. Значения в меню не может быть выбрано пользователем и показывается серым цветом.

    использование: используется только с для определения пунктов меню.

    SELECTED - определяет значение по умолчанию
    VALUE - определяет возвращаемое значение

    Примечание: в [ ] даны необязательные атрибуты


    Переменные среды CGI

    Для того, чтобы Web-узлы были действительно интерактивными, она должны обмениваться информацией с пользователем, а не только позволять ему загружать документы. Используя программы Common Gateway Interface ( называемые CGI-скриптами ), можно создавать Web-страницы, управляемые данными. Как вы узнаете, используя скрипты CGI, узел может получать запросы и отвечать пользователю.

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

    Почему Web-узлы используют CGI

    Для создания динамических файлов HTML нет необходимости в применении CGI-скриптов. Однако без таких скриптов всякий раз, когда понадобится новая интерактивная динамическая страница Web, придется модифицировать программу-сервер. Спустя какое-то время программа-сервер может стать исключительно большой. Для того чтобы исключить такую модификацию сервера, разработчики используют CGI. Используя CGI-скрипты, сервер может переложить задачу создания линамических Web-документов на прикладную программу, созданную для этих специфических потребностей. Вы будете создавать вашу прикладную программу, используя C/C++, Perl, JavaScript, VBScript, или какой-либо другой язык программирования.

    Программа-сервер должна вызвать CGI-скрипт

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

    Броузер, сервер и CGI

    Как известно, для получения броузером HTML-документов, он сначала устанавливает контакт с сервером, затем запрашивает документ ( обычно ваш броузер определяет GET-метод HTTP для получения информации от сервера ). Далее, если документ существует, сервер отвечает броузеру, посылая ему HTML-документ, и затем закрывает соединение. Применение CGI-скриптов вносит изменения в этот процесс только на стороне сервера. Броузер не знает, что сервер вызывает CGI-скрипт, и он не заботится о том, каким именно способом поступают к нему данные от сервера. Как Web-программист, при написании CGI-скриптов вы заботитесь только о входах и выходах сервера. Броузер будет устанавливать контакт с программой сервера, которая, в свою очередь, исполняет CGI-скрипт. Ваш скрипт, в свою очередь, выполняет необходимую обработку данных, чтобы сформатировать требуемый выход. Обычно ваш сервер передает выходные данные из скрипта в форме HTML-броузеру. Чтобы выполнить это, верверная программа добавляет необходимую заголовочную информацию к выходным данным, сформированным скриптом, и посылает эту заголовочную информацию вместе с данными обратно броузеру. Затем сервер закрывает соединение и ждет новых запросов.

    Как вы, возможно, знаете, серверы, которые работают под 32-битными операционными системами, такими как Windows 95/98 или Windows NT, могут обрабатывать запросы от многих пользователей одновременно. Отсюда следуте, что несколько пользователей могут одновременно использовать скрипт. Поэтому каждый из них, в зависимости от запроса, будет видетьь свою картину ответа сервера.

    Взаимосвязь сервера и CGI-скрипта

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

    Как вы уже знаете, HTTP является протоколом, с помощью которого клиенты и серверы Web обеспечиваются информацией. Заголовочная HTTP информация помогает программам эффективно выполнять обмен данными. Поэтому необходимо уделить особое внимание заголовочной информации, которой сервер снабжает броузер. Например, когда программа-сервер готова послать данные броузеру, она посылает заголовки, описывающие статус данных, тип данных и т.д. В свою очередь броузер использует заголовок ( Content-type ) для подготовки к выводу данных на экран. Сервер отвечает за то, чтобы обеспечить этой метаинформацией броузер каждый раз, когда он посылает ему данные.

    CGI т базы данных

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

    Где находятся скрипты

    Стандарты CGI не предписывают, куда должны помещаться скрипты, то есть не определяют заранее диск и каталог. Обычно Web-сервер ожидает найти скрипты в каталоге /CGI-BIN, который расположен нажи каталога самой программы сервера. Если вы помещаете свои скрипты на чей-то сервер, необходимо определить каталог для своих файлов, содержащих скрипты.

    Расширение имен файлов CGI-скриптов

    Серверы HTTP для Windows-систем обычно для CGI-файлов используют расшерение EXE или PL. Например, если вы создаете CGI-программу ( скрипт ), используя язык программирования С, то расширение ваших файлов-скриптов будет, вероятно, ЕХЕ. Аналогично, если вы создаете скрипт с помощью языка Perl, расширение ваших файлов будет PL.

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

    Основы взаимодействия между Web-сервером и CGI-скриптом

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

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

    Переменные окружения

    Переменная AUTH_TYPE

    Скрипты CGI используют переменную окружения AUTH_TYPE для идентификации пользователя, который пытается получить доступ к скрипту. Если сервер сконфигурирован так, чтобы поддерживать идентификацию пользователя, то пользователь, пытающийся получить доступ к скрипту, должен назвать свое имя и пароль. Например, следующее значение переменной означет, что от пользователя требуется основной уровень идентификации:

    Переменная CONTENT_LENGTH

    Скрипты используют переменную окружения CONTENT_LENGTH для того, чтобы определить точное число байт, содержащихся в просоединенных данных. Например, если запрос содержит документ длиной в 1,024 байта, то переменной окружения присваивается следующее значение:

    Переменная CONTENT_TYPE

    Скрипты используют эту переменную окружения для запросов, которые содержат присоединенную информацию. К такому типу запросов отоносится HTTP-операция POST. Содержащаяся в переменной информация указывает на тип присоединенных данных ( MIME-тип.подтип). Например, если запрос содержит присоединенный документ HTML , то переменная окружения будет принимать следующие значения:

    Переменная GATEWAY_INTERFACE

    Скрипты используют эту переменную для того, чтобы определить версию, номер выпуска спецификации CGI, которой удовлетворяет Web-сервер. Формат номера выпуска спецификации следующий: CGI/номер выпуска. Например, для CGI выпуска 1.1 переменная окружения будет иметь следующий вид:

    Переменная PATH_INFO

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

    Путь записывается в относительной форме, где за базу берется корневой каталог сервера. Иными словами, корневой каталог сервера является базисом для относительного пути, который и присваивается переменной PATH_INFO. Например, если задан путь c:/cgi-bin/example1.exe/sports.html, то переменная окружения будет иметь следующий вид:

    Переменная PATH_TRANSLATED

    Скрипты используют эту переменную для получения окончательной, пригодной для непосредственного использования информации относительно пути. Сервер переводит информацию переменной путем выполнения необходимых преобразований пути. Например, если переменная PATH_TRANSLATED имеет значение /sports.html, а корневым дирикторием сервера служит c:\, то переменная окружения будет иметь следующее значение:

    Переменная QUERY_STIRNG

    Скрипты используют эту переменную для того, чтобы получить информацию в текстовой форме ( состоящую из аргументов ), которая следует справа от знака вопроса после URL, переданного от пользователя скрипту для обработки. Эта текстовая сторока содежит вход для скрипта. Далее сервер заменяет в данном тексте каждый пробел на знак " + ", а все непечатные символы знаком " %dd", где d является базой десятичной системы счисления.

    Скрипт должен содержать код для расшифровки этой текстовой строки. Сервер, передавая эту информацию скрипту, не должен заниматься декодированием информации запроса каким-либо образом. Сервер должен также установить переменную QUERY_STRING в случае, если пользователь обеспечивает какую-то информацию запроса. Например, для URL http://www.jamsa.com/cgi-bin/grandma.exe?name=margaret+alarcon переменная окружения имеет значением следующую величину:

    Переменная REMOTE_ADDR

    Скрипты используют эту переменную для получения IP-адресса удаленного узла ( броузера ), который делает запрос. Например, значение переменной окружения может быть следующим:

    Переменная REMOTE_HOST

    Скрипты используют эту переменную для того, чтобы получить имя узла, с которого делается запрос. Если сервер не знает имя узла, делающего запрос, то сервер должен присвоить значение переменной окружения REMOTE_ADDR и не присваивать значения переменной REMOTE_HOST . Напрмиер, для узла jamsa.com переменная окружения будет содержать следующее значение:

    Переменная REMOTE_ >Используется для того, чтобы получиь имя удаленного пользователя, делающего запрос к серверу. Программа Web-сервера представляет собой программное обеспечение. вызывающее ваш скрипт. Если HTTP Web-сервер поддерживает протокол RFS 931 (Authentication Server Protocol), то сервер установит эту переменную равной значению имени пользователя, которое имеется у сервера. Скрипты могут использовать эту переменную только для регестрации пользователя. Напрмер, если имя удаленного пользователя pschmauder и он назодится на удаленном узле jamsa.com , то переменная примет следующее значение:

    Переменная REMOTE_USER

    Используется для того, чтобы получить имя удаленного пользователя без имени узла, с которого он производит запрос. Если сервер поддерживает идентификацию пользователя и скрипт является защищенным, то сервер установит имя пользователя и присвоит его этой переменной. Например, предположим, что именем удаленного пользователя является pschmauder . Тогда переменная будет выглядеть следующим образом:

    Переменная REQUEST_METHOD

    Используется для того, чтобы определить тип HTTP-запроса, который послан броузером серверу и служит для вызова скриптов. Эта переменная может принимать значения GET, HEAD или POST. Например, если броузер посылает GET-метод, то переменная окружения содержит следующее:

    Переменная SCRIPT_NAME


    Переменная SERVER_NAME

    Использутся для того, чтобы определитьимя домена ли IP-адрес комрьютера, на котором раположен Web-сервер. Например, когда сервер возвращает IP-адрес, переменная окружения будет иметь вид, подобный следующему:

    Переменная SERVER_PORT

    Переменная SERVER_PROTOCOL

    Используется для того, чтобы определить имя и номер выпуска протокола, используемогоклиентом (броузером) для того, чтобы послать запрос к Web-серверу. Анализируя содержание переменной, скрипт может идентифицировать имя и номер выпуска протокола, который он должен использовать при передаче данных серверу. Формат имени протокола и номера выпуска следующий: протокол/номер выпуска. Например, для HTTP 1.1 переменная окружения будет иметь следующий вид:

    Переменная SERVER_SOFTWARE

    Как вы знаете, Web-сервер исполняет скрипты CGI. Поскольку скрипт может испольняться по-разному для различных серверных программ, скрипты используют эту переменную для того, чтобы определить имя программы Web-сервера и ее номер версии. Формат имени Web-сервера и номер версии должен передаваться CGI следующим образом: имя/версия. Например, для FOLK WEB - сервера версии 1.01 переменная окружения будет иметь седующий вид:

    SERVER_SOFTWARE = FolkWeb/1.01 (Windows-32bit)

    Дополнительные переменные окружения

    В дополнение к переменным окружения. обсуждавшимся ранее, сервер также помещает данные из заголовка запроса, полученного от клиента, в переменные окружения. Сервер присваивает значения переменным, чьи имена начинаются с префикса HTTP_, после которого идет имя заголовка. Сервер заменяет все символы переноса (-) в заголовке на (_). Сервер может также исключать любые заголовки, которые он уже обработал, используя переменные окружения, такие как AUTH_TYPE, CONTENT_TYPE и CONTENT_LENGTH.

    Переменная HTTP_ACCEPT

    Используется для того, чтобы определить, какие MIME-типы может принимать броузер. Они определены в HTTP-заголовках, которые броузер послал серверу. Как известно, MIME-тип задается в виде тип/расширение. Если имеется насколько MIME-типов, то они разделяются запятыми. Например, переменная окружения может принимать следующее значение:

    HTTP_ACCEPT = audio/aif, text/html, text/plain

    Переменная HTTP_USER_AGENT

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

    HTTP_USER_AGENT = Mozilla/2.01 Gold(Win95PE)

    Опции командной строки CGI

    Обычно CGI-скрипты используют командную строку в качестве входа для того, чтобы выполнить запрос ISINDEX, позволяющий добавить интерактивный поиск по ключевому слову к вашему HTML-документы. Однако не все серверные программы поддерживают ISINDEX-запрос. Броузер посылает запрос в виду командкной строки серверу. Программа сервера может идентифицировать входную командную строку, устанавливая, использовал ли броузер GET-метод HTTP и содержит ли строка URL символы uuencoded = .

    Если броузер использует GET-метод HTTP и строка URL-поиска не содержит символы uuencoded = , то запрос осуществляется в форме командной строки. Перед тем как сервер вызовет соответствующий скрипт, серверная программа должна расщепить командную строку, используя знак (+), для отделения параметров. Затем сервер выполняет дополнительное декодирование ( если необходимо ) каждого параметра, переданного в URL-строке поиска, и хранит каждый параметр-строку в массиве, названную argv .

    Дополнительное декодирование, выполняемое сервером, состоит в разделении отдельных строк, используя амперсанда (&) в качестве разделителя. Далее сервер расщепляет каждую из этих строк снова, используя знак (=) для того, чтобы отделить имя переменной, которое ставиться слева от знака (=), от значения переменной, которое стоит справа от (=). Сервер хранит число элементов, содержащихся в массиве argv , в переменной целого типа argс .

    Если сервер нашел знак равенства внутри строки QUERY_STRING переменной окружения, то он не будет посылать командную строку в качестве входа в скрипт. Также если по какой-то причине программа сервера не может послать массив argv скрипту, она обеспечит недекодированную информацию запроса в переменной окружения QUERY_STRING.

    Стандартный ввод ( STDIN )

    Когда броузер запрашивает сервер ( например, используя HTTP-метод POST ), информация, которую получает скрипт, приходит со стандартного дескриптора ввода stdin. Серверная программа посылает скрипту переменную окружения CONTENT_LENGTH. Эта переменная содержит число байт, которое сервер посылает скрипту через этот дескриптор. Скрипт может использовать значение переменной CONTENT_LENGTH для того, чтобы определить, сколько данных должно поступить со стандартного ввода. Сервер также снабжает скрипт переменной окружения CONTENT_TYPE, которая помогает скрипту определить, как обрабатывать получаемые данные. В конце этого потока данных сервер может послать ( а может и не посылать ) маркер конца файла. Однако именно скрипт обязан определить, какой объем данных читать, и использует он для этого переменную окружения CONTENT_LENGTH.

    Например, если форму использует HTTP-метод POST ( ) и посланные серверу данные закодированы следующим образом: name=alberta&husband=art , то сервер присвоит переменным CONTENT_LENGHT и CONTENT_TYPEследующие значения:

    Стандартный вывод (STDOUT)

    После того как CGI-скрипт закончит обрабатывать полученные от сервера данные, он должен посылать свой ответ серверу. Для того, чтобы послать свои данные серверу, он должен посылать их файловому дескриптору стандартного выводы STDOUT. В общем случае данные, которые скрипт посылает назад серверу, представляет собой HTTP-ответ, включающий заголовок, после которого идет пустая строка и за ней остальная часть ответа. Обычно выходом скрипта служат документы HTML, созданные скриптом.

    Прямой ответ скрипта броузеру

    Обычно скрипт выдает ответ, который сервер интерпретирует и посылает назад броузеру. Преимуществом посылки выходных данных от скрипта серверу служит то, что скрипт в таком случае не обязан посылать полный заголовок HTTP на каждый запрос. Однако некоторые скрипты разгружают сервер и шлют свои выходные данные прямо броузеру. Для того, чтобы можно было отличить такие скрипты, которые шлют данные непосредственно броузеру, от скриптов, которые направляют их серверу, протокол CGI требует, чтобы имена скриптов, осуществляющих прямую посылку броузеру, начинались с букв nph- ( которые говорят серверу Not to Parse the Header - не инициализировать заголовок ). Если имя скрипта начинается так, то сервер не будет вставлять заголовок в данные скрипта. В таком случае ответственность возлагается на сам скрипт.

    Заголовки CGI

    Как вы узнали ранее, выходные данные скрипта начинаются с заголовка. Этот заголовок состоит из строки текста в том же формате, что и заголовок HTTP, оканчиваясь пустой строкой ( строкой, которая содержит только CRLF ). Если выходные данные скрипта содержат заголовки, не являющиеся директивами серверу, то сервер посылает эти заголовки броузеру в ответе на его запрос. Текущая спецификация CGI пределяет три директивы:

    • CONTENT-TYPE
    • LOCATION
    • STATUS

    Поле Content-type в заголовке CGI определяет тип/расширение MIME-данных, которые скрипт посылает назад броузеру. Обычно скрипты выдают на выходе документ HTML. В этом случае заголовок CGI Content-type содержит следующее:

    Поле Location заголовка указывает на документ. Скрипты обычно используют поле Location для указания местонахождения документа. В случае, если документ находится не на сервере и содержимым поля является URL, сервер перенаправляет броузерна соответствующий узел. Если же документ находится на сервере и поле представляет собой виртуальный путь, сервер выдает этот документ броузеру. Например, для того чтобы указать на документ на удаленном сервере, значение поля в заголовке может иметь вид:

    Поле Status заголовка содержит значение статуса HTTP, которое сервер направляет от скрипта броузеру. Сервер, который вызывает скрипт, использует различные коды статуса HTTP. Вы можете захотеть направлять код статуса прямо броузеру, особенно в случае возникновения ошибок.

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

    CGI-программирование на ассемблере. – Легко!

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

    Теория CGI

    CGI – (Common Gateway Interface) – Общий Шлюзовый Интерфейс. Как не трудно догадаться интерфейс этот служит шлюзом между сервером (здесь я подразумеваю программу — сервер) и какой-либо внешней программой написанной для ОС на которой этот самый сервер запущен. Таким образом CGI отвечает за то, каким именно образом данные будут переданы от программы-сервера к CGI-программе и обратно. Интерфейс не накладывает никаких ограничений на то, на чем должна быть написана CGI-программа, это может быть как обычный исполнимый файл, так и любой другой файл – главное, чтобы сервер смог его запустить (в среде windows это например может быть файл с расширением, привязанным к какой-либо программе).
    С момента когда Вы вызвали (например нажали кнопку формы, к которой привязан вызов CGI-программы) CGI-программу до получения вами результата в окно браузера происходит следующее:
    — Вэб-клиент (например браузер) создает подключение к серверу, указанному в URL;
    — Вэб-клиент посылает запрос серверу, запрос этот обычно делается с помощью двух методов GET или POST;
    — Данные из запроса клиента (например значения полей формы) передаются сервером, используя CGI-интерфейс, CGI-программе, указанной в URL;
    — CGI-программа обрабатывает данные клиента, полученные от сервера и генерирует на основе этой обработки ответ клиенту, который она передает по все тому же CGI-интерфейсу серверу, а он в свою очередь передает его уже непосредственно клиенту;
    — Сервер разрывает соединение с клиентом.
    В стандартной спецификации CGI принято, что сервер может обмениваться с программой следующими способами:
    — Переменные окружения – они могут быть установлены сервером при запуске программы;
    — Стандартный поток ввода (STDIN) – с его помощью сервер может передать данные программе;
    — Стандартный поток вывода (STDOUT) – программа может писать в него свой вывод, передающийся серверу;
    — Командная строка – в ней сервер может передать некоторые параметры программе.
    Стандартные потоки ввода/вывода весьма удобны и широко используются на UNIX-системах, чего не скажешь о windows, поэтому существует спецификация CGI, разработанная специально для windows-систем так и называемая «Windows CGI». Но, естественно, и стандартные потоки ввода/вывода так же можно использовать в windows CGI программировании. Здесь я не буду затрагивать стандарт «Windows CGI», и на это существует по крайней мере две причины – первая, и самая главная – на данный момент не все http-сервера под windows поддерживают эту спецификацию (в частности мой любимый Apache 1.3.19). Вторую причину вы можете наблюдать набрав в любой поисковой системе строчку «Windows CGI». Отмечу относительно этого интерфейса лишь общие детали – все данные от сервера к клиенту передаются посредством обычного для windows *.ini файла, имя которого передается программе в командной строке. При этом все данные в файле уже заботливо разбиты по секциям сервером и вам лишь остается используя функции «GetPrivateProfile*» извлечь их оттуда. Ответ серверу передается опять же посредством файла, имя которого указано в соответствующей записи ini-файла.
    Какие же данные могут быть переданы клиентом CGI-программе? – практически любые. В общем случае программе передаются значения полей формы, которые заполняет клиент, но это также могут быть и какие-либо двоичные данные, например файл с картинкой или музыкой. Данные могут быть переданы на сервер двумя различными методами – это метод GET и метод POST. Когда мы создаем форму для заполнения на нашей страничке мы явно указываем каким из приведенных методов мы хотим отправить введенные пользователем данные, делается это в основном тэге формы примерно так:
    При отправке данных методом GET, данные браузером считываются из формы и помещаются следом за URL скрипта, за знаком вопроса, если значимых полей в форме несколько, то они передаются все через значёк «&», имя поля и его значение пишутся в URL через знак «=». Например запрос, сгенерированный браузером из формы при нажатии на кнопку, к которой привязан скрипт «/cgi-bin/test.exe», при учете что первое поле формы называется «your_name», второе – «your_age», может выглядеть так:
    GET /cgi-bin/test.exe?your_name=Pupkin&your_age=90 HTTP/1.0
    Использование метода GET имеет сразу несколько слабых сторон – первое и самое главное – т.к. данные передаются в URL то он имеет ограничение на количество этих самых передаваемых данных. Вторая слабость опять же вытекает из URL – это конфиденциальность, при такой передаче данные остаются абсолютно открытыми. Итак, хорошо если у нас в форме 2-3 небольших поля… встает вопрос что же делать если данных больше? Ответ – использовать метод POST!
    При использовании метода POST данные передаются серверу как блок данных, а не в URL, что несколько развязывает нам руки для увеличения объема передаваемой информации, для вышеприведенного примера формы POST блок, посылаемый серверу будет примерно такой:

    POST /cgi-bin/test.exe HTTP/1.0
    Accept: text/plain
    Accept: text/html
    Accept: */*
    Content-type: application/x-www-form-urlencoded
    Content-length: 36
    your_name=Pupkin&your_age=90

    Как уже говорилось выше, после получения данных сервер должен преобразовать их и передать CGI программе. В стандартной спецификации CGI введенные клиентом данные при запросе GET помещаются сервером в переменную среды программы «QUERY_STRING». При запросе POST данные помещаются в стандартный поток ввода приложения, откуда могут быть им считаны. Кроме того, при таком запросе сервером устанавливаются еще две переменные среды — CONTENT_LENGTH и CONTENT_TYPE, по которым можно судить о длине запроса в байтах и о его содержании.
    Помимо самих данных сервером устанавливаются и другие переменные окружения вызываемой программы, приведу некоторые из них:

    REQUEST_METHOD
    Описывает каким именно методом получены данные
    Пример:REQUEST_METHOD=GET

    QUERY_STRING
    Строка запроса, если использовался метод GET
    Пример:QUERY_STRING= your_name=Pupkin&your_age=90&hobby=asm

    CONTENT_LENGTH
    Длина в байтах тела запроса
    Пример:CONTENT_LENGTH=31

    CONTENT_TYPE
    Тип тела запроса

    GATEWAY_INTERFACE
    Версия протокола CGI
    Пример:GATEWAY_INTERFACE=CGI/1.1

    REMOTE_ADDR
    IP-Адрес удаленного хоста, то бишь клиента, нажавшего кнопочку в форме
    Пример:REMOTE_ADDR=10.21.23.10

    REMOTE_HOST
    Имя удаленного хоста, это может быть его доменное имя или например имя компьютера в среде Windows, если таковые получены быть не могут, то поле содержит его IP
    Пример:REMOTE_HOST=wasm.ru

    SCRIPT_NAME
    Имя скрипта, использованное в запросе.
    Пример:SCRIPT_NAME=/cgi-bin/gols.pl

    SCRIPT_FILENAME
    Имя файла скрипта на сервере.
    Пример:SCRIPT_FILENAME=c:/page/cgi-bin/gols.pl


    SERVER_SOFTWARE
    Программное обеспечение сервера
    Пример:Apache/1.3.19 (WIN32)
    Вызываемая CGI-программа может прочитать любую из переменных своего окружения, установленных сервером и использовать ее в своих интересах.
    В общем-то это вкратце все, для получения более подробной информации о Общем Шлюзовом Интерфейсе смотрите специализированную документацию, это описание я сделал для того, чтобы напомнить вам, а если не знали то ввести в курс дела. Давайте попробуем что-нибудь сделать на практике.

    Практическая часть

    Для практики нам понадобятся как минимум 3 вещи – какой-нибудь http-сервер для Windows, все примеры я пробовал на Apache 1.3.19 для Windows, сервер бесплатный, скачать его можно с i
    Да, и сервер нам понадобится не абы – какой, а настроенный для запуска cgi-скриптов! Как это делается для сервера используемого вами смотрите документацию. Вторая вещь, которая нам понадобится это, естественно, ассемблер, так же необходимо, чтобы компилятор поддерживал создание консольных WIN32 приложений, я использую Tasm, но прекрасно подойдут и Fasm и Masm и множество других *asm’ов. Ну и наконец самое главное, что потребуется это желание.
    Итак, я допускаю, что сервер был вами благополучно поставлен и настроен, так, что в корневой директории документов сервера лежит файлик index.html, который замечательно показывается в браузере, когда вы набираете адрес 127.0.0.1. Так же я учту, что где-то в дебрях папок сервера существует папочка «cgi-bin», в которой разрешен запуск скриптов.
    Давайте проверим настройку сервера, а заодно и напишем небольшой скрипт. Скрипт наш будет обычным *.bat файлом. Предвижу вопросы – как? неужели? Да, это обычный командный файл, как уже говорилось выше спецификация CGI не делает различий между типами файлов, главное, чтобы сервер мог его запустить, а он в свою очередь, имел доступ к stdin/stdout и переменным окружения, bat-файл, пусть и не в полной мере, но для примера нас вполне устроит. Создадим файл примерно такого содержания:

    @echo off
    rem Заголовок апроса
    echo Content-type: text/html
    echo.
    rem Тело запроса
    echo "Привет!

    echo "С запросом GET пришли данные: %QUERY_STRING%

    Файл назовем test.bat и поместим его в директорию для запуска скриптов, скорее всего это будет директория «cgi-bin». Следующее, что нам нужно будет сделать, это каким либо образом вызвать этот скрипт, в принципе, сделать это можно напрямую набрав в окошке адреса браузера примерно следующее «http://127.0.0.1/cgi-bin/test.bat», но давайте сделаем его вызов с нашей главной странички, заодно проверим работу метода GET. Создадим в корне сервера файл index.html со следующим содержанием:

    Теперь при входе на сервер (http://127.0.0.1 в строке адреса браузера) должна появиться форма, наберите в ней что-нибудь и нажмите кнопку «послать», если все было сделано правильно, Вы увидите в окне браузера ответ нашего bat-скрипта. Теперь давайте посмотрим что же мы там намутили.
    Как можно догадаться команда «echo» осуществляет вывод в stdout, первым делом мы передаем серверу заголовок нашего ответа – «echo Content-type: text/html». Это есть стандартный заголовок спецификации CGI, говорящий о том, что передавать мы хотим текст или документ html, существуют и другие заголовки. Очень важный момент – заголовок должен отделяться от тела ответа пустой строкой, что мы и делаем следующей командой «echo.». Дальше передается тело самого ответа – это обычный html-документ, в теле документа я для наглядности отображая одну из переменных среды, переданной нам сервером – «QUERY_STRING», как уже говорилось при методе GET (а это именно наш случай) в этой переменной передаются все введенные пользователем данные, что мы и можем наблюдать в ответе скрипта. Вы могли заметить «кавычки не к месту» в последних 2-х строках файла, сразу после «echo», стоят они там из-за специфичности bat-файлов, как можно заметить тэги html обрамляются символами « », в тоже время эти символы служат перенаправлением ввода/вывода в bat-файлах, а посему мы не можем их здесь свободно использовать.
    Рекомендую немного побаловаться с подобными bat-скриптами, это бывает очень полезно, попробуйте посмотреть другие переменные окружения. Немного скажу, отступив от темы, на UNIX-системах языки командных интерпретаторов очень сильно развиты и грань между программированием на языке командного интерпретатора и программированием на «реальном» языке программирования весьма и весьма размыта в некоторых случаях, поэтому на UNIX-системах частенько простенькие скрипты пишутся именно на языках командных интерпретаторов, но windows-интерпретатор cmd.exe или, ранее, command.com явно слабоваты для этих целей.
    Теперь перейдем к самой главной задаче этой статьи, к собственно написанию CGI-программы на ассемблере. В принципе, если учесть все вышесказанное о CGI мы можем сделать вывод о том, что требует CGI-интерфейс от нашей программы:

    • Программа должна уметь читать стандартный поток ввода (stdin), чтобы получить доступ к данным, переданным методом POST;
    • Программа должна уметь писать в стандартный поток вывода (stdout), чтобы передать результат своей работы серверу;
    • Из первых двух пунктов следует, то, что для того, чтобы сервер мог передать нашей программе что-либо в stdin, а она могла ему что-либо ответить в stdout CGI-программа должна быть консольным приложением;
    • Наша программа должна уметь читать переменные своего окружения.

    Этого вполне достаточно для создания полноценного CGI-приложения.
    Начнем с последнего пункта. Для получения доступа к переменным окружения Windows-приложения используется функция API «GetEnvironmentStrings», функция не имеет аргументов и возвращает указатель на массив переменных окружения (ИМЯ=ЗНАЧЕНИЕ) разделенных между собой нулем, массив закрывается двойным нулем, при запуске программы сервером в окружение программы помимо стандартных переменных добавляются специфические CGI-переменные, описанные выше, при запуске программы из командной строки вы их не увидите, естественно.
    Для того, что бы писать что-то в stdout или читать из stdin сначала мы должны получить хэндлы этих потоков, делается это с помощью функции API «GetStdHandle», в качестве параметра функции передается одно из следующих значений:

    • STD_INPUT_HANDLE — для stdin (стандартный ввод);
    • STD_OUTPUT_HANDLE — для stdout (стандартный вывод);
    • STD_ERROR_HANDLE — для stderr.

    Функция возвратит необходимый нам для операций чтения/записи хэндл. Следующее что нам необходимо делать это писать/читать эти потоки. Делается это обычными операциями чтения/записи файлов, т.е. ReadFile и WriteFile. Тут есть одна тонкость, можно подумать, что для этих целей можно использовать WriteConsole/ReadConsole, да это действительно справедливо для консоли и будет прекрасно работать, результаты, так же как и с WriteFile будут выводиться на консоль, но продолжаться это будет пока мы не запустим нашу программу как скрипт на сервере. Происходит это потому что, когда нашу программу запускает сервер хндлы, возвращаемые функцией «GetStdHandle» уже не будут хндлами консоли как таковыми, они будут хэндлами pipe, что необходимо для связи двух приложений.
    Вот небольшой пример того, как должна выглядеть CGI-программа на ассемблере:

    .386
    .model flat,stdcall
    includelib import32.lib
    .const
    PAGE_READWRITE = 4h
    MEM_COMMIT = 1000h
    MEM_RESERVE = 2000h
    STD_INPUT_HANDLE = -10
    STD_OUTPUT_HANDLE = -11

    .data
    hStdout dd ?
    hStdin dd ?
    hMem dd ?
    header:
    db 'Content-Type: text/html',13,10,13,10,0
    start_html:
    db 'Окружение CGI-программы выглядит так:
    ',13,10,0
    for_stdin:
    db 'STDIN программы содержит:
    ',13,10,0
    end_html:

    db '',13,10,0
    nwritten dd ?
    toscr db 10 dup (32)
    db ' - Тип файла',0
    .code
    _start:

    xor ebx,ebx
    call GetStdHandle,STD_OUTPUT_HANDLE
    mov hStdout,eax
    call GetStdHandle,STD_INPUT_HANDLE
    mov hStdin,eax

    call write_stdout, offset header
    call write_stdout, offset start_html

    call VirtualAlloc,ebx,1000,MEM_COMMIT+MEM_RESERVE,PAGE_READWRITE
    mov hMem,eax
    mov edi,eax
    call GetEnvironmentStringsA
    mov esi,eax
    next_symbol:
    mov al,[esi]
    or al,al
    jz end_string
    mov [edi],al
    next_string:
    cmpsb
    jmp short next_symbol
    end_string:
    mov [edi],'>rb

    Учебное пособие по CGI-программированию
    Страница 2. Переменные среды CGI

    Переменные среды CGI

    Предыдущий скрипт не содержал ничего особенно замечательного,так просто вываливал HTMLый текст который благополучно и отбражался на екране браузера.Но По настоящему мощь придает CGI возможность обработки параметров,которые переданы скрипту.например вы можете набрать
    http://www.somehost.ru/somedir/cgi-bin/my_cgi.cgi?param=value
    то есть вы хотите чтоб скрипт my_cgi.cgi обработал для вас параметер param со значением value (ну это например) или когда вы заполнили запрос в форме (в например yahoo или altavista).Ну это с точки зрения пользователя. А на сервере при запуске CGI-скрипта сервер формирует среду окружения в которой скрипт может найти всю доступную информацию о HTTP-соединении и о запросе.
    Вот эти переменные:

    REQUEST_METHOD

    Это одно из самых главных поле используемое для определения метода запроса HTTP Протокол HTTP использует методы GET и POST для запроса к серверу.Они отличаются тем что при методе GET запрос является как-бы частью URL т.е. http://www. /myscript.cgi?request а при методе POST данные передаются в теле HTTP-запроса (при GET тело запроса пусто) и следовательно для CGI тоже есть различие при GET запрос идет в переменную QUERY_STRING а при POST подается на STDIN скрипта.
    Пример:REQUEST_METHOD=GET

    Это строка запроса при методе GET. Вам всем известно что запрос из формы кодируется браузером поскольку не все символы разрешены в URL некоторые имеют специальное назначение. Теперь о методе urlencode: неплохо бы чисто формально напомнить,что все пробелы заменяются в URL на знак '+', а все специальные и непечатные символы на последовательность %hh ,где hh-шестнадцатиричный код символа,разделитель полей формы знак '&',так что при обработке форм надо произвести декодирование.
    Пример:QUERY_STRING= name=quake+doomer&age=20&hobby=games

    Длина в байтах тела запроса.При методе запроса POST необходимо считать со стандартного входа STDIN CONTENT_LENGTH байт,а потом производить их обработку.Обычно методом POST пользуются для передачи форм,содержащих потенциально большие области ввода текста TEXTAREA.При этом методе нет никаких ограничений,а при методе GET существуют ограничения на длину URL .
    Пример:CONTENT_LENGTH=31

    Тип тела запроса(для форм кодированых выше указаным образом он application/x-www-form-urlencoded)

    Версия протокола CGI.
    Пример:GATEWAY_INTERFACE=CGI/1.1

    IP-Адрес удаленого хоста,делающего данный запрос.
    Пример:REMOTE_ADDR=139.142.24.157

    Если запрашивающий хост имеет доменное имя,то эта переменная содержит его, в противном случае -тот же самый IP-адресс что и REMOTE_ADDR
    Пример:REMOTE_HOST=idsoftware.com

    Имя скрипта,исполизованое в запросе.Для получения реального пути на сервере используйте SCRIPT_FILENAME
    Пример:SCRIPT_NAME=/

    Имя файла скрипта на сервере.
    Пример:SCRIPT_FILENAME=/home/p/paaa/public_html/cgi-bin/guestbook.cgi

    Имя серера ,чаще всего доменное как www.microsoft.com ,но в редких случаях за неимением такового может быть IP-адресом как 157.151.74.254
    Пример:SERVER_NAME=www.uic.nnov.ru

    TCP-Порт сервера используюшийся для соединения .По умолчаниию HTTP-порт 80, хотя может быть в некоторых случаях другим.
    Пример:SERVER_PORT=80

    Версия протокола сервера.
    Пример:SERVER_PROTOCOL=HTTP/1.1

    Програмное обеспечение сервера.
    Пример:Apache/1.0

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

    Переменные среды CGI

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

    CGI – (Common Gateway Interface) – Общий Шлюзовый Интерфейс. Как не трудно догадаться интерфейс этот служит шлюзом между сервером (здесь я подразумеваю программу - сервер) и какой-либо внешней программой написанной для ОС на которой этот самый сервер запущен. Таким образом CGI отвечает за то, каким именно образом данные будут переданы от программы-сервера к CGI-программе и обратно. Интерфейс не накладывает никаких ограничений на то, на чем должна быть написана CGI-программа, это может быть как обычный исполнимый файл, так и любой другой файл – главное, чтобы сервер смог его запустить (в среде windows это например может быть файл с расширением, привязанным к какой-либо программе).

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

    - Вэб-клиент (например браузер) создает подключение к серверу, указанному в URL;

    - Вэб-клиент посылает запрос серверу, запрос этот обычно делается с помощью двух методов GET или POST;

    - Данные из запроса клиента (например значения полей формы) передаются сервером, используя CGI-интерфейс, CGI-программе, указанной в URL;

    - CGI-программа обрабатывает данные клиента, полученные от сервера и генерирует на основе этой обработки ответ клиенту, который она передает по все тому же CGI-интерфейсу серверу, а он в свою очередь передает его уже непосредственно клиенту;

    - Сервер разрывает соединение с клиентом.

    В стандартной спецификации CGI принято, что сервер может обмениваться с программой следующими способами:

    - Переменные окружения – они могут быть установлены сервером при запуске программы;

    - Стандартный поток ввода (STDIN) – с его помощью сервер может передать данные программе;

    - Стандартный поток вывода (STDOUT) – программа может писать в него свой вывод, передающийся серверу;

    - Командная строка – в ней сервер может передать некоторые параметры программе.

    Стандартные потоки ввода/вывода весьма удобны и широко используются на UNIX-системах, чего не скажешь о windows, поэтому существует спецификация CGI, разработанная специально для windows-систем так и называемая «Windows CGI». Но, естественно, и стандартные потоки ввода/вывода так же можно использовать в windows CGI программировании. Здесь я не буду затрагивать стандарт «Windows CGI», и на это существует по крайней мере две причины – первая, и самая главная – на данный момент не все http-сервера под windows поддерживают эту спецификацию (в частности мой любимый Apache 1.3.19). Вторую причину вы можете наблюдать набрав в любой поисковой системе строчку «Windows CGI». Отмечу относительно этого интерфейса лишь общие детали – все данные от сервера к клиенту передаются посредством обычного для windows *.ini файла, имя которого передается программе в командной строке. При этом все данные в файле уже заботливо разбиты по секциям сервером и вам лишь остается используя функции «GetPrivateProfile*» извлечь их оттуда. Ответ серверу передается опять же посредством файла, имя которого указано в соответствующей записи ini-файла.

    Какие же данные могут быть переданы клиентом CGI-программе? – практически любые. В общем случае программе передаются значения полей формы, которые заполняет клиент, но это также могут быть и какие-либо двоичные данные, например файл с картинкой или музыкой. Данные могут быть переданы на сервер двумя различными методами – это метод GET и метод POST. Когда мы создаем форму для заполнения на нашей страничке мы явно указываем каким из приведенных методов мы хотим отправить введенные пользователем данные, делается это в основном тэге формы примерно так:

    Мастер Йода рекомендует:  Основы RSS
    Добавить комментарий