Cgissi пример счетчика


Содержание

Практическое использование SSI

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

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

Вот текст упомянутого выше сценария:

Как видно из примера даже во включаемых сценариях необходимо выводить HTTP заголовок.

В результате сканирования нашего простейшего документа пользователю будет возвращен примерно (с точностью до случайной величины) следующий документ:

Вторым распространенным применением SSI является формирование страницы из шаблона. В простейшем случае — это документ в начало и конец которого вставляются шапка и концевик:

Вставляемые блоки не обязательно должны быть законченными, например, header.html может заканчиваться тэгом , а global_menu.html или footer.html начинаться с тэга . Таким образом, какими бы навороченными не были шапка и концевик документа, редактируемый документ выглядит чрезвычайно просто, и его легко редактировать.

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

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

Теперь приведем пример файла, вставляемого в начало каждого документа сервера http://www.citforum.ru/. Особенностью сервера является то, что каждый раздел имеет свой базовый цвет, и все это создается этим единственным файлом:

Данный пример иллюстрирует работу с условными операторами, с шаблонами, а также возможность использования вложенных SSI.

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

_head.html

_item.html

_foot.html

А вот как выглядит на самом деле файл, который вы воспринимаете, как обычный HTML документ (он сокращен для удобства восприятия):

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

В заключение хотим сказать, что нами (а точнее А.Ю.) написан пакет подпрограмм для Perl, который позволяет включать HTML из CGI-скрипта с обработкой директив SSI внутри этого HTML. Лежит он у нас в Кладовой — http://www.webclub.ru/repository/archive/cgi-scripts/ssi-pl.tgz. Только мы должны вас предупредить — работают только базовые директивы, выражения не обрабатываются вовсе.

Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:

Библиотека Интернет Индустрии I2R.ru

Малобюджетные сайты.

Продвижение веб-сайта.

Контент и авторское право.

Что такое CGI?

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

Е сли это программа, то она должна иметь любой приемлемый для конкретной операционной системы исполняемый формат. Программы можно писать на чем угодно: C/C++, Pascal, Java, Visual и просто Basic, delphi и т.д.

Е сли это скрипт (сценарий), то на операционной системе, под которой крутиться веб-сервер должен быть соответствующий интерпретатор сценариев: shell, perl, tcl/tk, command.com и т.д.

Г лавное, чтобы средство разарботки CGI программы (скрипта) отвечало следующим требованиям: — позволяют читать из стандартного потока ввода (stdin) — получать значения переменных окружения (environment variables) — выводить в стандартный поток вывода (stdout)

Д ля чего используется CGI:

  • Работа со справочными системами и базами данных.
  • Создание динамических HTML документов и ресурсов (в том числе счетчики, гостевые книги и т.д.)
  • Удаленное администрирование различных систем.
  • Просто работа с различными программами, поскольку HTML интерфейс довольно удобен в использовании, прост в изготовлении и приятно выглядит :)

Механизм работы CGI программ

Переменные окружения (environment variables) — переменные, определенные для системы и сервера, на которой будет выполняться CGI. .

Стандартный поток вывода (stdout) — сюда программа (скрипт) выводит результаты своей работы. Обычно это экран, но его можно переназначит на файл, сокет, входной поток другой программы, принтер и т.д.

Б ольшинство примеров в этом руководстве написано на shell только для того, чтобы упростить изложение материала.

С огласно последним веяниям по соблюдению безопасности не рекомендуется использование shell для написания CGI скриптов.

1.1 Вызов CGI без параметров

П ростейший скрипт, выводящий текущую дату: #!/bin/sh echo Content-type: text/html echo echo «

Today is » date echo «

ВАЖНОЕ ЗАМЕЧАНИЕ Основной ошибкой, которую совершают почти все, кто начинает писать CGI программы или скрипты, заключается в том, что они забывают вставить указатель на тип выводимого результата — заголовок выводимого документа. Это вторая и третья строчки в примере. echo Content-type: text/html echo где Content-type: — тип выводимого документа (text/html, image/gif, image/jpeg и т.д.).
Пустая строка в выводе говорит о том, что заголовок кончился и далее следует собственно сам документ.

1.2 Передача параметров CGI скрипту или программе

П ередача параметров осуществляется двумя основными методами: GET и POST . У каждого из них свои достоинства и недостатки.

П ри использовании GET параметры добавляются к запрашиваемому URL и его можно вызывать таким образом: http://какой-то_хост/cgi-bin/какой-то_скрипт?параметры что позволяет делать на такой скрипт ссылки в HTML документах. А на сервере переданные параметры присваиваются переменной QUERY_STRING.

Текст самого скрипта: #!/bin/sh echo Content-type: text/html echo echo «

Вы посылали вот это:

Н о применение метода GET для передачи параметров, содержащих конфиденциальную информацию недопустимо, т.к. в данном случае вся эта информация передается открыто.

М етод POST позволяет обеспечить конфиденциальность при передаче параметров скрипту. Но он передает параметры на стандартный поток ввода и для этого приходится использовать формы. Сервер не посылает скрипту EOF в конце передачи. Вместо этого вам придется использовать пременную окружения CONTENT_LENGTH, чтобы определить какой объем данных вам надо считать из stdin.

Пишем счетчик

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

Э та глава руководства будет скорее полезна тем, кому интересен именно механизм работы счетчиков, поскольку все прилагаемые примеры особыми «наворотами» по части настроек, администрения, и т.п. не обладают. Более «навороченые», готовые к эксплуатации счетчики ищите на Altavista, Yahoo и др. поисковых серверах. Или спрашивайте в соответствующих конференциях новостей (relcom.www.users, relcom.www.support; в фидошных эхах ru.internet.*).

2.1 Типы счетчиков

где #command — любая из многочисленных команд понимаемых Web сервером. В данном случае наибольший интерес представляет команда #exec , которая позволяет выполнять программы и подставлять результаты их работы. Анализируемые Web сервером HTML документы называются server-parsed документами.

2.2 Cчетчик посещений работающий как SSI

А лгоритм работы:

  1. Сервер получает от браузера запрос на HTML документ.
  2. Сервер просматривает документ на наличие вызова SSI.
  3. Если такие вызовы обнаружены, то на их место подставляется результат. В случае команды #exec — результат работы программы, указанной в «value» .
  4. Сформированный HTML документ возвращается браузеру.

Н еобходимые настройки сервера (на примере сервера Apache):

  1. В файле srm.conf прописать (если там еще не прописано): AddType text/html .shtml AddHandler server-parsed .shtml Эти директивы говорят серверу, что файлы с раширением .shtml являются server-parsed документами.
  2. В файле access.conf на директорию, где будут лежать server-parsed документы, в Options добавить опцию Includes.
  3. Файлам, содержащим вызовы SSI присвоить расширение .shtml (см. п. 1)

Продемонстрируем работу счетчика на примере скрипта counter , найденного в Интернете на http://www.webtools.org/. Он написан на столь популярном ныне Perl’е.

В от тут будем считать :
(нажимайте Reload пока не надоест)

Э тот счетчик текстовый, т.е. скрипт возвращает просто текст, который и показывается. Аналогичным образом можно выводить и картинки. Для этого нужно, чтоб вместо текстовых цифр выводились тэги img src=»http://www.i2r.ru/static/260/%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0_%D1%81_%D1%81%D0%BE%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D0%B2%D1%83%D1%8E%D1%89%D0%B5%D0%B9_%D1%86%D0%B8%D1%84%D1%80%D0%BE%D0%B9″. Пытливый читатель легко догадается, что количество тегов img src. равно количеству цифр в значении возвращаемом счетчиком.

В ызов этого счетчика в теле документа осуществляется командой:

2.3 Счетчик не использующий SSI

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

  • в теле HTML документа указывается: т.е. запрашиваемая картинка не является статической, а динамически генерируется CGI скриптом.
  • сервер, получив запрос на картинку, запускает скрипт, указанный в src тэга img .
  • скрипт, увеличивает значение счетчика на единицу, генерирует картинку со значением счетчика и возвращает ее браузеру.

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

С крипт ( counter.cgi ), который вызывается в теле HTML документа тэгом img src=»http://www.i2r.ru/static/260/.%20counter.cgi» написан на shell и имеет следующий исходный текст (номера строк добавлены только для упрощения объяснения): 1: #!/bin/sh 2: now=`date -u` 3: echo «Content-type: image/gif;» 4: echo «Expires: $now» 5: echo 6: counter|showdigits


Ч то делает этот скрипт (построковое описание):
1 — Заголовок самого скрипта. Он указывает на командный интерпретатор, который будет его выполнять.

2 — Определяем переменную now , которая содержит время запуска скрипта (время создания картинки). Ключик ‘ -u ‘ говорит, что, дата/время создания выводяться в GMT . Зачем это надо будет описано ниже.

3 — Начинаем формировать заголовок ответа сервера. Указываем тип возвращаемых данных: image/gif

4 — Поскольку это счетчик, то необходимо обеспечить, чтобы картика с его показаниями не кэшировалась (а то какой он после этого счетчик:). Для этого указываем, что полученая браузером картинка должна немедленно заэкспайриться. Вот тут то мы и используем переменную now , определенную в строке номер 2. Употребление Expires в таком виде соответствует стандарту на HTTP протокол версии 1.1. Но при использовании Expires равным дате создания документа могут возникать забавные глюки, если часы на клиенте отстают от часов сервера на несколько минут. Возникает дилемма — по стандарту положено так, а получается не то что надо. Что делать? В предыдущей версии протокола (HTTP 1.0) Expires можно было выставлять равным 0, а RFC2068 гласит, что клиенты и кэши работающие по HTTP 1.1 должны поддерживать старый вариант использования Expires (Expires: 0). Так шта, дорогие россияне, решайте сами.

5 — Конец заголовка ответа — возвращаем пустую строку.

6 — Используя две программы (counter и showdigits) генерим саму картинку.

П рограммы counter и showdigits написаны на Си с использованием библиотеки для работы с GIF файлами — libgd. Без нее программы компилироваться не будут. Последнюю версию библиотеки всегда можно получить на http://www.boutell.com/gd/ .

Ч то делают эти программы:

  • counter — читает из файла counter.rc число, представляющее из себя предыдущее значение счетчика, прибавляет к нему единичку и пишет обратно. Если не указан путь к файлам — картинкам с цифрами и маска этих файлов,то береться дефолтовая, которая определна в теле программы. После этого она вычисленное значение счетчика и пути к картинкам выводяться на stdout, чем формируется коммандная строка для showdigits.
  • showdigits — эта программа, собственно, и формирует картинку с текущим показанием счетчика. Для этого используется набор готовых картинок с цифрами (gif формат, все картинки одинакового размера) и полученные на stdin от counter данные. По пути, маске и числу беруться нужные картинки и из них собирается один гиф. После чего он отправляется прямиком на . stdout ! А далее сервер перенапрявляет этот поток браузеру и он (браузер) показывает его как картинку, поскольку в заголовке ответа указано, что это гиф.

В ся суть здесь вот в чем: — Сервер передает браузеру поток данных. — Браузеру абсолютно все равно, где и как сервер взял передаваемый ему поток данных (статический ли это, или динамически сгенеренный; обычный файл или результат жизнедеятельности скрипта), главное, чтоб браузер знал как его правильно интерпретировать. Для этого служит заголовок, который в данном примере был сгенерирован скриптом counter.cgi , а именно в 3-5 строках (см. выше). Причем, в случае статических файлов сервер сам генерирует этот заголовок, исходя из собственных настроек, а в случае с cgi это должен делать сам скрипт.

Server side includes


3.1 Что такое SSI

где #command — любая из SSI директив понимаемых Web сервером, а » value » — ее параметры.

Подставляемые данные могут быть статическими и динамически генерируемыми. Статические данные уже готовые, записанные в виде файлов, фрагменты текста или HTML. Такие данные удобно применять в случае, когда в различных HTML документах содержаться повторяющиеся фрагменты. Динамически генерируемые данные результаты работы каких-либо CGI скриптов или команд операционной системы, на которой работает конкретный Web-сервер. Использование этого типа данных предоставляет Web-девелоперу огромные возможности. Но, как гласит дебильная российско-буржуйская реклама, — «Не забывай про Орбит без сахара!». То бишь, ПОМНИ О МЕРАХ ПО СОБЛЮДЕНИЮ БЕЗОПАСНОСТИ ДОСТУПА К ИНФОРМАЦИИ! Неправильное использование SSI может привести к появлению возможности несанкционированного доступа к информации и, соответственно, к различным тяжким последствиям. Чтобы уберечься от этого — читайте необходимую литературу. Например, от W3C (master site: http://www.w3.org/Security/Faq/) или одно из его многочисленных. В том числе и на русском: http://private.peterlink.ru/www-security-faq/.

3.2 Основные SSI директивы

CGI скрипту передаются так же значения переменных PATH_INFO и QUERY_STRING оригинального запроса клиента.

cmd сервер выполняет указанную строку, используя командный интерпретатор операционной системы. fsize печатает размер указанного файла с учетом sizefmt . Атрибуты: file указывается путь к файлу относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный путь к файлу. Если путь не начинается с (/), считается, что путь указан относительно текущего документа. flastmod печатает дату/время последнего изменения указанного файла с учетом timefmt . Атрибуты такие же как у команды fsize . include вставляет текст другого документа или файла в анализируемый документ. Очень полезна при повторяющихся фрагментах в разных документах. Атрибуты: file указывается путь к файлу только относительно текущей директории содержащей анализируемый файл. virtual указывается (%-кодированый) URL-относительный путь к файлу. Если путь не начинается с (/), считается, что путь указан относительно текущего документа. В Apache включаемые таким образом файлы могут быть вложенными. printenv печатает список всех существующих переменных и их значения. Атрибутов нет. Пример:
set устанавливает значение переменной. Атрибуты: var указывается имя устанавливаемой переменной. value указывается значение устанавливаемой переменной. Пример:

3.3 SSI переменные окружения

DOCUMENT_URI — виртуальный путь к файлу Описание в теле документа: Результат использования:

QUERY_STRING_UNESCAPED — раскодированя query string, причем все метасимволы shell предваряются «\» Описание в теле документа: Результат использования:

DATE_LOCAL — текущая дата и время (местное) Описание в теле документа: Результат использования:

DATE_GMT — текущая дата и время (GMT) Описание в теле документа: Результат использования:

LAST_MODIFIED — дата и время последнего изменения файла Описание в теле документа: Результат использования:

3.4 Настройка сервера

Д ля того, чтобы серевер знал, в каком месте в документе подставлять данные, он должен этот документ проанализировать. Анализируемые сервером документы называются server-parsed документами.

В первую очередь надо дать понять серверу, какие документы он должен анализировать. Для этого в файл конигурации (для Apache старых версий и NCSA web-серверов это файл srm.conf , а для новых версий Apache, например 1.3.4 — httpd.conf ), нужно добавить следующие параметры: Сервер Apache: AddType text/html .shtml
AddHandler server-parsed .shtml

AddType text/x-server-parsed-html .shtml Указанные параметры говорят о том, что все файлы с расширением .shtml являются server-parsed , и перед тем как «отдать» этот документ клиенту сервер должен их проанализировать.

Зачем указывать отдельное расширение для server-parsed документов?,- спросит пытливый читатель. Отвечаем. Конечно, никто не мешает добавить в файл конфигурации строку AddType text/x-server-parsed-html .html Однако это приведет к тому, что сервер будет анализировать все документы с расширением .html, даже если в них нет вызова SSI, загрузка системы увеличиться, а производительность сервера снизится.

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

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

Приложения


Приложение 1. Переменные окружения сервера

Н иже приведен список основных переменных окружения сервера с краткими описанием назначения.В данном случае сервер Apache 1.2.5 с модулем PHP/FI-2.0.1. Для других веб-серверов (MS IIS, Netscape, NCSA httpd, и т.д.) переменные могут отличаться.

REMOTE_HOST — имя хоста приконнектившегося к серверу. В случае работы через прокси — имя прокси.
Пример: REMOTE_HOST=lom.pvrr.ru

REMOTE_ADDR — IP адрес хоста приконнектившегося к серверу. В случае работы через прокси — IP адрес прокси.
Пример: REMOTE_ADDR=194.87.186.11

REMOTE_PORT — номер порта клиента.
Пример: REMOTE_PORT=3381

HTTP_USER_AGENT — имя/номер версии/и т.д. клиента (браузера). Использование этой переменной иногда приводит в бешенство отдельных пользователей Интернет.:) Но на самом деле очень полезная вещь. Например для автоопределения русских кодировок.
Пример:HTTP_USER_AGENT=Mozilla/4.07 [en] (X11; I; FreeBSD 2.2.6-RELEASE i386)

HTTP_ACCEPT — типы данных, помимо text/html, воспринимаемые клиентом (браузером)
Пример: HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*

HTTP_ACCEPT_CHARSET — какие чарсеты понимает клиент (браузер).
Пример: HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8

HTTP_ACCEPT_LANGUAGE — какие языки воспринимвает клиент (браузер).
Пример: HTTP_ACCEPT_LANGUAGE=nl,nl-BE,ru

SERVER_NAME — имя сервера соответствующее записи IN A в DNS, или значение переменной ServerName (или похожей) в конфиге сервера.
Пример: SERVER_NAME=arche.pvrr.ru

HTTP_HOST — имя сервера или виртуального хоста, к которому обращается клиент. Значение HTTP_HOST может быть равным значению SERVER_NAME.
Пример: HTTP_HOST=www.pvrr.ru

SERVER_SOFTWARE — какое ПО используется в качестве сервера.
Пример: SERVER_SOFTWARE=Apache/1.2.5 PHP/FI-2.0.1

DOCUMENT_ROOT — путь к «корню» веб-сервера от «корня» файловой системы копьютера, на котором он работает.
Пример: DOCUMENT_ROOT=/usr/local/www/html

HTTP_CONNECTION — тип соединения.
Пример: HTTP_CONNECTION=keep-alive

SERVER_PROTOCOL — протокол, используемый для обмена данными с конкретным клиентом.
Пример: SERVER_PROTOCOL=HTTP/1.0

REQUEST_URI — имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. При обращении к корню сервера или каталогу этой переменной присваивается имя каталога или «/» в случае корня сервера.
Пример: REQUEST_URI=/cgi-bin/tralala/script.cgi

DOCUMENT_URI — имя запрашиваемого ресурса/документа, включающее в себя путь от корня веб-сервера. Обычно инициализируется при вызове SSI. В отличие от REQUEST_URI эта переменная, в случае обращения к каталогу или корню сервера получает значение содержащее и имя файла, являющегося Directory Index’ом этого каталога.
Пример: DOCUMENT_URI=/tralala/index.shtml

HTTP_REFERER — полный URL документа, по ссылке с которого вы попали на этот сервер. Эту переменную можно использовать при написании счетчиков.
Пример: HTTP_REFERER=http://lom.pvrr.ru/java/cgi/cgi_1.html

GATEWAY_INTERFACE — название/версия интерфейса, через который сервер работает со скриптом.
Пример: GATEWAY_INTERFACE=CGI/1.1

SCRIPT_FILENAME — имя скрипта, содержащее полный путь от «корня» файловой системы.
Пример:SCRIPT_FILENAME=/usr/local/www/cgi-bin/tralala/script.cgi

SCRIPT_NAME — имя скрипта, содержащее путь от «корня» веб-сервера.
Пример: SCRIPT_NAME=/cgi-bin/tralala/script.cgi

REQUEST_METHOD — метод используемый клиентом для передачи данных серверу. Бывают GET, HEAD, POST, PUT.
Пример: REQUEST_METHOD=GET

QUERY_STRING — этой переменной значение присваивается при передаче данных серверу методом GET
Пример: QUERY_STRING=button=on

CONTENT_LENGTH — этой переменной присваивается значение, равное количеству байт, переданных браузером серверу при использовании метода POST.
Пример: CONTENT_LENGTH=9

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

PATH_INFO — дополнительная информация о пути, которую передал клиент. То есть скрипт может получать некоторые параметры, содержащие информауцию о некотором «пути» к некоторым данным (например к файлу конфигурации, необходимому для обработки запроса отименно этого клиента). Этот путь «виртуальный» — т.е от «корня веб-сервера». Остальные данные можно передавать как обычно — методом GET или POST.
Пример: PATH_INFO=/some/path

PATH_TRANSLATED — то же , что и PATH_INFO, только путь физический — «от корня файловой системы»

REMOTE_IDENT — Если HTTP сервер поддерживает идентификацию согласно RFC 931, то этой переменной присваивается имя пользователя получаемое от сервера.

SERVER_ADMIN — e-mail администратора веб-сервера.
Пример: SERVER_ADMIN=webmaster@www.pvrr.ru

SERVER_PORT — порт, который «слушает» веб-сервер.
Пример: SERVER_PORT=80

HTTP_X_FORWARDED_FOR — в случае работы через прокси — IP адрес клиента, работаеющего через прокси.
Пример: HTTP_X_FORWARDED_FOR=194.87.186.11

HTTP_VIA — имя, номер порта, версия ПО прокси-сервера.
Пример: HTTP_VIA=1.0 proxy1.pvrr.ru:8080 (Squid/2.1.PATCH1)

HTTP_CACHE_CONTROL — что-то связанное с возрастом документа в кэше прокси сервера:) Врать не буду — не знаю:)
Пример: HTTP_CACHE_CONTROL=max-age=259200

SSI (Server S >


Содержание

Общая информация

Основным, наиболее простым, но в то же время чрезвычайно мощным инструментом поддержки больших наборов документов является SSI (Server-Side Includes — включения на стороне сервера). С помощью SSI можно не только в зависимости от некоторых условий выводить определенные части документа, не только формировать документ из заранее определенных кусочков, но и вставлять результат работы некоторого CGI сценария или программы прямо в документ.

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

В стандартном дистрибутиве Apache есть модуль mod_include. Начиная с версии 1.2, он имеет расширенное количество директив и называется — XSSI (eXtended SSI). По умолчанию он включен в компиляцию.

Активация механизма Server-Side Includes

Мы предоставляем своим клиентам возможность использовать директивы SSI на тарифных планах «maxi» и «ultra», тарифный план «mini» позволяет исполнять SSI инструкции только в режиме «NoExec».

Любой документ, у которого будет установлен обработчик «server-parsed», будет сканироваться этим модулем, если включена опция «Includes». При малом количестве документов с SSI, лучше всего в файле httpd.conf (в случае администрирования в автоматическом режиме данные строки уже присутствуют) указать следующее:

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

Однако, стоит помнить, что в этом случае на сервер ляжет дополнительная нагрузка по проверке всех документов вида *.html.

Также следует включить в опции директории узла параметр Includes:

Практическое использование SSI

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

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

Вот текст упомянутого выше сценария:

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

В результате сканирования нашего простейшего документа пользователю будет возвращен примерно (с точностью до случайной величины) следующий документ:

Вторым распространенным применением SSI является формирование страницы из шаблона. В простейшем случае — это документ, в начало и конец которого вставляются шапка и подвал:

Вставляемые блоки не обязательно должны быть законченными, например, header.html может заканчиваться тэгом

, а global_menu.html или footer.html начинаться с тэга

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

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

Cgissi пример счетчика

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

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

С уважением,
команда разработчиков eManual.ru

Описание SSI на русском языке.

Описание SSI на русском языке
Server Side Includes Структура команд SSI+ Основные команды SSI+ Примеры использования SSI+ Команда echo Команда include Команда fsize Команда flastmod Команда exec Команда if Команда goto Команда label Команда break

Технология создания активных документов SSI+ — Server Side Includes предложена фирмой Questar Microsystems. Эту технологию поддерживают такие WWW сервера как Apache , Netscape, Spry Web и Microsoft Internet Information Server.

Поддержка этой технологии связанна с специальной конфигурацией WWW сервера и протокола HTTP.

Технология Server side includes (SSI) позволяет использовать в HTML документах такие возможности как: опрос текущего времени и даты, условного выполнения форматирования в зависимости от логических сравнений, формировать запросы или модифицировать базы данных, посылать электронную почту, вызывать программы или CGI scripts.

Возможности технологии SSI+ задают механизм совместного использования языка HTML и программ CGI Script.

Формат команды SSI+:

‘ »

где: ‘ одна из следующих команд: ‘echo’, ‘include’,
‘fsize’, ‘flastmod’, ‘exec’, ‘config’, ‘odbc’, ’email’, ‘if’,
‘goto’, ‘label’, ‘break’ параметры (атрибуты) команды, значения которых зависят от командой . Формат задания переменных такой же как и формат задания атрибутов для команд языка HTML: ‘=’ ‘»‘ variable data ‘»‘ ‘=’ ‘»‘ variable data2 ‘»‘
‘=’ ‘»‘ variable datan ‘»‘ » конец обращения к SSI команде. Отметим, что в отличии от обычных команд языка HTML для команд SSI+ задание значений переменных-атрибутов должно обязательно заключаться в «двойные кавычки» («) (для языка HTML значения атрибутов заключаются в двойные кавычки только в случае когда они содержат служебные символы или пробелы).
Заметим, что если сервер и просмотрщик не поддерживают режима работы SSI, то команды SSI воспринимаются просто как коментарии и не выводятся на экран просмотрщика.

Чать команд SSI имеют подкоманды, управляющие их работой, например, команды if, odbc, email, и exec. Формат подкоманды следующий:

‘&&’ ‘&&’

где: ‘&&’ зарезерированный символ для обозначения начала и конца подкоманды. имя подкоманды. Замечание о SSI документах
SSI+ документ по умолчанию имет префикс (расширение) ‘.SHT’ или ‘.SHTM’ для их отличия от обычных HTML документов, которые имеют префикс ‘.HTML’ или .HTM.
Хотя при конфигурации сервера можно обявить все документы как SSI, но это снижает его эффективность.

Основные команды SSI+

‘echo’ Включение значений CGI переменых в HTML документ.
‘include’ Включение файла в HTML документ.
‘fsize’ Включение размера файла в HTML документ.
‘flastmod’ Включение даты последней модификации файла в HTML документ.
‘exec’ Выполнение внешнего исполняемого файла (CGI программы). Выходной поток данных (стандартный вывод) этой программы включается в документ.
‘config’ Установка параметров для SSI+ команд.
‘odbc’ Оращение к внешней ODBC СУБД.
’email’ Отправка электронной почты или представление формы.
‘if’ Условный оператор, управляющий выполнением других команд SSI и вывода документа.
‘goto’ Оператор перехода на определенную SSI метку (‘label’).
‘label’ Метка в документе.
‘break’ Остановка вывода документа.

Включение значений переменных окружения в HTML документ. Команда echo имеет только одну переменную var
Пример:

Вы используете просмотрщик

Если данный документ просматривается через просмотрщик MS Internet Explorer 3.0 for Windows 95, то эта команда даст следующий результат

Вы используете просмотрщик Mozilla/2.0 (compatible; MSIE 3.0; Windows 95)

А для просмотрщика, через который вы сейчас читаете этот текст, получим

Вы используете просмотрщик Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)

WWW сервер, соторый понимает технологию SSI, как правило, использует описанные ниже переменные окружения. Кроме того, если на сервере разрешено выполнение испольнаяемых модулей (CGI Script программы), то в документе могут быть использованы и переменные окружения CGI. «DOCUMENT_NAME» локальное имя документа. «DOCUMENT_URI» локальный путь к документу от базовой директории WWW сервера. «QUERY_STRING_UNESCAPED» Строка, полученная от клиента, содежащая все shell-special characters escaped with % «DATE_LOCAL» Текущая локальная дата и время. «DATE_GMT» Дата и время по Гринвичу (Greenwich). «LAST_MODIFIED» Дата последней модификации текущего документа. «REMOTE_ADDR» IP адрес удаленного клиента. «QUERY_STRING» Строка, полученная от клиента. «SERVER_SOFTWARE» Имя HTTP server software. «SERVER_NAME» Имя компьютера, на котором работает WWW сервер. «GATEWAY_INTERFACE» Имя и версия Common Gateway Interface served WWW (HTTP) сервера (name/version). «SERVER_PROTOCOL» Имя и версия HTTP сервера (name/version). «SERVER_PORT» IP порт WWW (HTTP) сервера. «REQUEST_METHOD» Тип метода запроса к серверу. «PATH_INFO» Виртуальный путь, указанный в запросе (путь от базовой диретории WWW сервера). «PATH_TRANSLATED» Полный путь, указанный в запросе. «SCRIPT_NAME» Имя программы для выполнения в CGI запросе. «REMOTE_HOST» Имя компьютера удаленного клиента. «AUTH_TYPE» Переменная для определения авторизованного метода доступа к серверу (authentication method). «REMOTE_USER» Имя пользователя для авторизованного метода доступа. «REMOTE_IDENT» Имя удаленного клиета, используемое для идентификации пользователя, согласно спецификации RFC931. «CONTENT_TYPE» Тип передачи данных от клиета по методам POST или PUT. «CONTENT_LENGTH» Длина в байтах переданных данных по методам POST или PUT. «HTTP_ACCEPT» Список, разделенный запятыми, MIME типов, понимаемых просмотрщиком клиента. «HTTP_USER_AGENT» Имя просмотрщика клиента (browser software). «HTTP_REFERER» ULR адрес HTML документа из которого сделан запрос клиентом. «HTTP_FROM» Имя (подобное имени Е-mail address) удаленного клиента. «HTTP_FORWARDED» Имя Proxy Server, через который общается клиент. «ACCEPT_LANGUGE» Список языков доступных для копьютера клиента. «HTTP_COOKIE» Содержение ответа клиента на запрос от сервера (см. ниже).

По команде ‘include’ на место этой команды подставляется содержимое файла, на который она указывает.

Команда имеет два параметра-переменных: virtual для задания относительного адреса файла на WWW сервере. file для задания абсолютного адреса файла на компьютере, на которм установлен WWW сервер. Пример:

Далее между двумя горизонтальными чертами следут вставленный в документ файл include.txt из текущей директории. Начало вставки
Данный текст вставлен в документ из файла include.txt
Конец вставки

fsize Вывод размера файла в документ.
Команда имеет два параметра-переменных: virtual для задания относительного адреса файла на WWW сервере. file для задания абсолютного адреса файла на компьютере, на которм установлен WWW сервер. Пример:

Выдача размера файла, который вы в данный момент читаете:
Размер файла ssi.shtml = 35k

Формат выдачи размера соответсвует установке сервера и может быть изменен командой config.

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

Пример:

Включение даты последней модификации файла ‘ssi.shtml’ в документ:
Дата последней модификации файла ssi.shtml = Monday, 10-Mar-1997 00:00:00 NS.

Формат выдачи даты и времени соответсвует установке сервера и может быть изменен командой config.

Выполнене внешних программ и программ CGI Script.

Парамеры: ‘cmd‘ задане командной строки параметров для выполнения UNIX shell исполняемых программ. Формат командной строки:

где: полное имя исполняемой программы или команды, и список аргументов, посылаемых исполняемой программе в командной строке.
Замечание: на сервере должны быть заданы пути к исполняемой программе в переменной окружения ‘PATH’.
В случае отсутвия пути программу можно запустить, используя shell или CGI Script. Стандартный вывод программы направляется в HTML документ. Вывод может быть модифицирован командой ‘config..cmdecho’. ‘cgi‘ вызов программы CGI Script. Вызываемая программа должна находится в директории CGI-BIN WWW сервера или иметь префикс, например, .cgi, который задан для Shell программ в конфигурационном файле сервера. Формат команды:

где полное имя программы CGI Script.
Стандартный вывод программы подставляется в документ.

Команда config модифицирует вывод в HTML документ.

Парамеры-атрибуты команды: ‘errmsg‘ The errmsg variable is used to set the error message that gets printed when the SSI+ engine encounters a parsing error or unavailable required data. This variable is retained for compatability with standard SSI, you may wish to use the onerr variable instead. ‘timefmt‘ Установка формата выдачи времемени в команде echo..time SSI+ token output. ‘sizefmt‘ The sizefmt variable is used to set the format ofecho..size SSI+ token output. ‘cmdecho‘ The cmdecho variable is used to set the output option of subsequent exec..cmd tokens. The format is ‘cmdecho’='» «‘where is either ‘ON‘ or ‘OFF‘. When the SSI+ parsing engine encounters an exec..cmd token it executes the command. If the command returns output then that output may be echoed into the HTML document or it may be ignored. The format of the data echoed is dependent on the presence or absence of config..cmdprefix and config..cmdpostfix tokens in the document. In the absence of config..cmdprefix and config..cmdpostfix tokens the output will be echoed exactly as returned with no formatting and no special character interpretation. In the presence of config..cmdprefix and/or config..cmdpostfix tokens the output will be formatted and interpreted. To activate echoing set cmdecho to ‘ON’ otherwise set it to ‘OFF’. The default is ‘OFF’. ‘cmdprefix‘ The cmdprefix variable is used to set the string prefixed to each line out output from subsequent exec..cmd tokens. The format is ‘cmdprefix=»‘ «‘where is any character string and/or HTML format tags. When the SSI+ parsing engine encounters an exec..cmdtoken it executes the command. If the command returns output then that output may be echoed into the HTML document or it maybe ignored. If the output is echoed (see ‘cmdecho’ above),then each line output from the executable will be prefixed with the string supplied before being echoed into the HTML document. ‘cmdpostfix‘ The cmdpostfix variable is used to set the string appended to the end of each line out output from subsequent exec..cmd tokens. The format is ‘cmdpostfix=»‘ «‘where is any character string and/or HTML format tags. When the SSI+ parsing engine encounters an exec..cmdtoken it executes the command. If the command returns output then that output may be echoed into the HTML document or it maybe ignored. If the output is echoed (see ‘cmdecho’ above),then each line output from the executable will be appended with the string supplied before being echoed into the HTML document. ‘onerr‘ The onerr variable is used to set the action to be taken when the SSI+ engine encounters an error. The format is ‘onerr=»‘»‘where is one of the following tags. ‘goto‘ causes a jump to a label token (see below). The format of the goto tag is: ‘goto’ where is the name of a label defined in a subsequent label tag (see below). ‘print‘ causes text to be printed. The format of the print tag is: ‘print «‘

is any HTML text or tag. ‘error‘ causes the current config..error message to be printed. ‘break‘ causes termination of the HTML document transmission to the client. ‘errorbreak‘ causes the current config..error message to be printed, and then causes termination of the HTML document transmission to the client. ‘printbreak‘ causes text to be printed, and then causes termination of the HTML document transmission to the client. The format of the printbreak tag is the same as the format of the print tag.

Example. The following token on an HTML document sets the SSI+ error message to ‘*** ERROR ***’. From this point on down when an error occurs in the SSI+ parsing engine the message ‘*** ERROR ***’will be inserted into the HTML document at the location of the offending SSI+ statement.

Example. The following token on an HTML document sets the SSI+ error action to print a message and terminate the document. From this point on down when an error occurs in the SSI+ parsing engine the message will be inserted into the HTML document at the location of the offending SSI+ statement, and the document will be terminated

Example. Suppose you wish to create an HTML document that performs a ‘PING’ operation on address ‘204.96.64.171’ and then echo the results back to the client browser, with each line echoed as an element in an unnumbered list. Insert the following lines into your HTML document: When the document is accessed by a remote browser the output would look something like this: Pinging 204.96.64.171 with 32 bytes of data: Reply from 204.96.64.171: bytes=32 time «‘ where; is any string and is reserved for future use.

The connect variable is used to connect to a pre-existing odbc data source, to allow for subsequent statement tag operations on that data source. The format of the connect variable is ‘connect=»‘ ‘,’ ‘,’

‘»‘where ; is the name odbc data source as defined on the local system in the odbc configuration utility. CAUTION! the account under which the server is run must be granted permission to access the data source. is the name which to log into the data source.


is the password with which to access the data source.

Example. To connect to a data source called ‘odbcsht’ as user ‘dufus’ and password ‘dorkboy’, one would use the following statement: .

The statement variable is used to submit a Transact SQL statement to the odbc data source. The format of a statement variable is as follows: ‘statement=»‘ ‘»‘,where: is any Transact SQL statement as defined in odbc and SQL reference text and help files.

Example. Suppose one wanted to query the ‘CUSTOMERS’ table from the above connected ‘odbcsht’ database to return all rows and display each row on a separate line. One may use the following sequence of statements: Connect to the database with a connect token as described above. Setup the output format with a statement token as described below. Execute the query: Each row of the database will the be inserted into the HTML page per the format statement as demonstrated below.

The format variable is used to prov >'»‘where; is a standard C language printf format string with the restriction of only allowing string (%s) insertions. The user is referred to any C language text for a description of this format. The number of instances of %s must be equal to the number of fields selected in a the subsequent SQL SELECT statement token.

Example. Suppose one wanted to query the ‘CUSTOMERS’ table from the above connected ‘odbcsht’ database to display the columns ‘name’, ‘age’, and ‘viscosity’ with each row on a separate line. One may use the following sequence of statements: Connect to the database with a connect token as described above. Setup the output format: . Execute the query with a statement token as described above. Each row of the database will the be inserted into the HTML page per the format statement. For example if the database has 3 rows the HTML output would look something like this: Customer’s name is Conan, and he is 29 years old, he prefers a motor oil with SPF 15 viscosity Customer’s name is Kevin, and he is 45 years old, he prefers a motor oil with SPF 30 viscosity Customer’s name is Alan, and he is 43 years old, he prefers a motor oil with SPF 50 viscosity

’email’
Отправка элктронной почты.
Пример:

При отработке данного примера будет отправлено электроное письмо (e-mail), содержание которого задано атрибутом message, по адресу, определенному атрибутом toaddress, если данный адрес и host, заданный атрибутом tohost (данный атрибут может отсутсвовать), реально существует.

The email tag prov >'»‘ where := ‘ON’ to enable debugging := ‘OFF’ to disable debugging, this is the default action if the debug variable is omitted. ‘fromhost’ defines the name of the smtp host sending the mail. ‘tohost’ defines the name of the smtp host the mail will be sent to. ‘fromaddress’ defines the email address from party. ‘toaddress’ defines the email address of the recipient party. ‘message’ defines the message body to be sent. ‘subject’ defines the subject field of the message to be sent. ‘sender’ defines the email address sending party. ‘replyto’ defines the email address to which replies should be sent. ‘cc’ defines the courtesy copy email addresses. ‘inreplyto’ defines the inreplyto field of the message to be sent. ‘id’ defines the id field of the message to be sent.

Example. The following document send an email with debugging enabled. Supposewe have a form with datum : [First, Last, Middle Initial, Company,Address1, Address2, City, State, Zip, Country, Phone, Fax, Request,Urgency, ReplyMethod; Email, Subject, Message] we may post thatform to an HTML document containing the following fragment tosend an email.

The if tag provides for conditional execution of SSI operations, and conditional printing of HTML text, based on logical comparisons. The format of the if tag is :

where: is the first operand of a logical comparison statement is the second operand of a logical comparison statement is the logical comparison method [‘==’, ‘!=’,’ ‘, ‘! ‘] is the action to take if the logical comparison evaluates to TRUE [‘goto’, ‘print’, ‘error’, ‘break’, ‘errorbreak’, ‘printbreak’]

The operands may be any string or number (integer or floating point). In the event that both operands are numbers the comparison will be based on the value of the numbers. In the event that one or both of the operands and not numbers, the comparison will be based on the alphabetic order of the operands.

The special case of the NULL operand is defined by two quotes with no characters between them. The NULL operand may used to check for the existence of form data from the remote client (see example below). The operator defines what kind of comparison is performed on the operands: ‘==’ The equalto operator evaluates to TRUE if the operands are equal to each other. ‘!=’ The notequalto operator evaluates to TRUE if the operands are not equal to each other. ‘ ‘ The greaterthan operator evaluates to TRUE if operand1 is greater than operand2 ‘! ‘ The notgreaterthan operator evaluates to TRUE if operand1 is not greater than operand2 ‘hasstring’ The hasstring operator returns TRUE is the text string in operand2 is found in the operand1 string.

In the event that the logical comparison evaluates to FALSE, nothing happens, If the logical comparison evaluates to TRUE then one of the following operations may be performed: ‘goto’ causes a jump to a label token (see below).The format of the goto tag is: ‘goto’ where is the name of a label defined in a subsequent label tag (see below). ‘print’ causes text to be printed. The format of the print tag is: ‘print’

is any HTML text or tag. ‘error’ causes the current config..error message to be printed. ‘break’ causes termination of the HTML document transmission to the client. ‘errorbreak’ causes the current config..error message to be printed, and then causes termination of the HTML document transmission to the client. ‘printbreak’ causes text to be printed, and then causes termination of the HTML document transmission to the client. The format of the printbreak tag is the same as the format of the print tag.

Example. The following document fragment compares two numbers, if the operands are not equal then a goto will jump to a label.

This should not print

This should print

Example. The following document fragment demonstrates conditional execution based on data delivered from an HTML form. Suppose we have two form datum called ‘formdata1’ and ‘formdata2’ and we wish to compare them. The following document fragment compares the two operands, if the operands are equal then a goto will jump to a label. Otherwise the next line will print and the document will terminate on a break token (see below).

The operands are not equal.

operands are equal.

Example. The following document fragment prints two different statements depending on whether or not the client agent is NCSA Mosaic.

You are not using Mosaic

You are using Mosaic

Example. Suppose we have a form with amongst other things a field named «BOO» and we wish to make sure that the remote client user enterted data into the «BOO» field before submitting the form. The following document fragment checks for the presence of data in the «BOO» field, if data exists then nothing happens, if data does not exist then a message will be displayed and the document will terminate.

Команда goto оператор перехода на маетку label.
Формат команды:

«

где имя метки, определенное командой label.

Пример.

This line will not print.

This line will print.

Замечание: Между сиволами «

где строка из не более чем 51 символа без пробелов, идентиифицирующая место в документе.

Задание метки не влияет на форматирование документа.

Cgissi пример счетчика

Дурным стилем сайтостроительства считается наличие в документе гиперссылок на этот же документ. Ссылаться на самого себя неразумно — пользователь от нажатия на гиперссылку ожидает, что загрузится другая страница, а также такого рода ссылки доставляют большие неудобства пользователям каналов с низкой пропускной способностью. Такие ссылки на себя часто получаются при включении колонтитулов. Для того чтобы избежать таких ссылок, оформляйте каждый пункт меню в колонтитулах следующим образом: Данный SSI-код используется на сайте http://my-elecon.ru.

Другой не менее важный SSI-код применяется для организации версии страниц для печати. Версия страницы сайта для печати отличается от обычной страницы отсутствием колонститулов, навигации, баннеров и прочей лишней информации. Рассмотрим, как организована версия для печати на примере сайта http://alavus.ru.

При нажатии на гиперссылку «версия для печати» страница, на которой находится пользователь, перегружается. Но поскольку в строке запроса присутствует параметр for_printing, то лишний HTML-код не включается на страницу. Обратите внимание . Это строка запроса CGI-параметров. В обычном случае, у вас никаких параметров, кроме for_printing нет, но когда появляются на сайте CGI-модули, то появляются и дополнительные параметры. Забегая вперед расскажу, как делать «Версию для печати» В CGI-программе. Пока веб-сервер Apache не может обрабатывать на SSI-директивы вывод CGI-программ. Такую возможность обещают в новых версиях Apache. У CGI-программистов есть два пути либо самим разобрать SSI-директивы в файле head.inc либо, что значительно проще, создать ручками файл phead.inc и подключать его в CGI-программах.

Условные операторы записываются следующим образом: Для примера приведу SSI-код для вывода времени последней модификации документа в приемлемом виде. Как вы уже видели, команда выдает совершенно не приемлемую строчку — Monday, 26-Feb-2001 19:25:58 Московское время (зима), для размещения ее на солидном веб-сайте. Нам бы хотелось получить что-нибудь, вроде 26 Февраля 2001 года. Для этого существует команда config с параметром timefmt, которая задает формат вывода даты. Например, в нашем случае нам требуется следующий вариант , тогда результат будет 26 February 2001. Но это пока все равно не то, что бы нам хотелось. Для определения месяца мы воспользуемся условными операторами. Вот, как будет выглядеть этот код: Соответственно, чтобы получить дату в формате 26 Февраля 2001.
Вот полный список значение параметра timefmt:

Формат Описание Пример
%a Аббревиатура названия дня недели Sun
%A Полное название дня недели Sunday
%b Аббревиатура названия месяца Jan
%B Полное название месяца January
%d День месяца 01 (не 1)
%D Дата в формате «%m/%d/%y» 01/31/90
%e День месяца 1
%H Часы в 24-часовом формате 13
%I Часы в 12-часовом формате 01
%j День года 235
%m Номер месяца 01
%M Минуты 03
%p AM|PM AM
%r Время в формате «%I:%M:%S %p» 11:35:46 PM
%S Секунды 34
%s Время в секундах с 01.01.1970 957228726
%T Время в формате «%H:%M:%S» 14:05:34
%U Неделя года 49
%w Номер дня недели 5
%y Год в формате ГГ 95
%Y Год в формате ГГГГ 1995
%Z Временная зона MSK

Далее приведены несколько полезных SSI-директив. Допустим, вы распространяете какие-либо утилиты и выкладываете ссылки на файлы для скачивания. Например, такие ссылки вы найдете на сайте http://www.oxygensoftware.com. Для удобства пользователей неплохо было бы указать размер файла и иногда, дату его последней модификации. Каждый раз после выкладывания на сервер новых версий файла, модифицировать самому ручками все размеры и даты долго и мучительно. Server Side Includes приходят на помощь.

Прозрачный gif-файл
Дата модификации:
Размер: байта
Если у вас файлы больших размеров, то информацию лучше выводить в килобайтах. Для этого установите формат вывода размера файла следующим образом.
При возникновение какой-либо ошибки, например, при попытки включить в HTML-документ файл, которого не существует веб-сервер выдаст следующее сообщение:

Сообщение не слишком информативно и пугает пользователя, не так ли? Давайте изменим сообщение об ошибке следующей SSI-директивой
Теперь сообщение об ошибке вылядит так:

Оглавление:

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

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

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

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

Вот это самое главное в запросе

Ну тут дальше идет посылаемая браузером информация о себе и о том что более подробно ему надо.(Например Accept: */*)

Ну и если запрошен простой файл например .html то если если такой файл есть, То сервер отошлет браузеру ответ:

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

Итак . приступим.

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

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

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

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

cd public_html
mkdir cgi-bin
chmod 0777 cgi-bin

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

chmod +x first.cgi

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

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

perl -с first.cgi

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

Разберем скрипт:
Первая строка #!/usr/bin/perl Просто указывает где в системе расположен компилятор Perl. Обычно он находится /usr/bin/perl или /usr/local/bin/perl ,выяснить это можно одной из комманд или ну или (что очень долго) запустить полный поиск .
Вторая строка это просто коментарий -вы можете тыкать чо угодно после знака #, однако я пишу обычно во второй строке название скрипта, что очень удобно.
Затем идет print «Content-Type: text/html\n\n»; Это заголовок указывающий тип содержимого.
Все что скрипт печатает в свой стандартный вывод STDOUT идет на обработку к серверу. Пустая строка отделяет заголовок от тела,которое в нашем случае представляет собой
Сервер обработает ответ скрипта и на базе него сформирует и пошлет браузеру ответ.(Сервер обычно не изменяет тела сообщения,он только дополняет заголовок нужными для работы протокола 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-соединении и о запросе.
Вот эти переменные:

Это одно из самых главных поле используемое для определения метода запроса 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)

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

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

Давая запрос на сервер браузер обычно расчитывает получить информацию определеного формата,и для этого он в заголовке запроса указывает поле Accept:,Отсюда скрипту поступает cписок тех MIME,которые браузер готов принять в качестве ответа от сервера.
Пример:HTTP_ACCEPT=text/html,text/plain,image/gif

Браузер обычно посылает на сервер и информацию о себе,чтоб базируясь на знании особеностей и недостатков конкретных браузеров CGI-скрипт мог выдать информацию с учетом этого. Например,разные браузеры могут поддерживать или не поддерживать какие-то HTMLые тэги.
Пример:HTTP_USER_AGENT=Mozila/2.01 Gold(Win95;I)

Имя хоста к которому обращается браузер. Так как физически на одном сервере может находиться сразу много серверов (Виртуальные Хосты), то должен быть способ сообщить серверу к какому именно идет обращение. Скрипт же может тоже в зависимости от этой переменной производить различные действия, таким если он используется на сайтах сразу нескольких виртуальных хостов.
Пример:HTTP_HOST=www.nnov.city.ru

Ну,начнем применять на практике усвоеные уроки. Так как все ваши .cgi -файлы должны быть исполняемыми то чтоб облегчить себе жизнь заведите себе в директории cgi-bin командный файл mkcgi ,содержащий и сделайте его в свою очередь исполняемым chmod +x mkcgi -он сильно упростит вам жизнь.
Ну а теперь запускайте скрипт.
Изучив информацию,выдаваемую данным скриптом вы сможете лучше ориентироваться в переменных окружения CGI.

Прекрасный язык Perl

Вы наверное обратили свое внимание что CGI скрипты пишутся обычно на языке Perl (Practical Extraction and Report Language)— очень удобном языке,впитавшем из других все лучшие черты.Может у вас возникнуть сомнение :Ну вот!Изучать новый язык программирования!? Спешу вас успокоить,изучение Perl не будет в тягость (я сужу по своему опыту!). Вы даже сами не заметите как выучите его.Если вы хоть когда-нибудь программировали скажем на C и использовали утилиту grep для поиска регулярных выражений в тексте,то вам будет еще легче. Для Perl родной платформой является Unix поэтому пользователям PC он мало известен. Мое целенаправленое доведение Perl до широкой публики началось с того что я скачал Perl под Windows (фирмы ActiveWare) К нему прилагается отличная гипертекстовая HTML— документация, даже быстрого просмотра которой хватит , чтобы начать хорошо и широко использовать его. Хоть он значительно уступает и по скорости и по эффективности своему Unix’ному аналогу, все равно самый лучший способ изучить язык это программировать на нем. Если вы как я дома используете большую часть времени не Windows а Unix то с изучением Perl у вас вообще не должно быть особых сложностей. Я же от себя могу сказать, что даже после небольшого опыта изучения его, он стал моим любимым языком программирования.

Все в нем сделано для удобства программиста (в отличии например от Java ;( )
Начнем с переменных,они в Perl бывают 3х типов скаларные,списковые(массивы) и хэши(ассоциативные массивы). Для указания компилятору(да и для немалого удобства программиста) перед именем скалярной переменной стоит знак ‘$’ перед массивом ‘@’,перед хешем ‘%’. т.е. например $scalar_var,@array_var,%hash_var Скалярные переменные могут быть как числовые так и строковые,но это не надо указывать Perl сам по контексту в зависимости от операций может привести одно к другому.
Например: «123»+»4″ будет 127 (или «127») так как операция ‘+’ действует над числами а вот если применить операцию конкатенации строк ‘.’ то строковое «test» . 1 будет «test1»
Ну а вот операции над скалярными переменными:

Операцыи Описание Пример
+ — * / % Арифметические print 2*7+4/(8%3);
print int(127/15); #целая часть
** Возведение в степень print 2**16;
++ — Инкремент-декремент $i++;
& | ^

>

Побитовые $x=3;$y=4;
print $x|$y;
print $x&$y;
== != = Числовые операции сравнения if($x==9)
eq ne lt gt le ge cmp стрковые операции сравнения if($game eq ‘doom’)
|| && ! Логические if(($x==9)||($game eq ‘doom’))
?: Условный оператор $x=($game eq ‘quake’?9:8);
, Последовательное вычисление $x=10,$y=20;
. Конкатенация $x=’http://’.’www.uic.nnov.ru’;
x Повторение $x=’1234’x5; #$x=’12341234123412341234′
=

Сопоставление с образцом if($url= То же но с отрицанием if($url!

= >= .= x=

Присваивание $x+=$y;

Пусь это будет вам справочником ,да кстати насчет строк,вы заметили,что они могут быть в двойных и одинарных кавычках, разница между ними состоит в том ,что в одинарных не осуществляется подстановка переменных, а в двойных осущестляется, Например: Списки: Спискочные переменные начинаются с символа ‘@’ конструируются следующим образом Также можно список использовать как lvalue: Можно обращаться к нескольким,выбраным элементам массива(срезу массива): Обратится к скаларному значению -элементу массива можно $имя_массива[индекс], сдесь обратите внимание на знак ‘$’— мы ведь обращаемся к скаляру-элементу.
Теперь немного о хешах:
хеш это такой массив который состоит из пар ключ-значение, весь хеш обозначается %хеш ,к отдельным элементам доступ $хеш конструируется хеш так: Хеш может быть также сконструирован из массива с четным числом элементов где пары превращаются в ключ-значение удаление из хеша -операция delete: есть функции выдающие ключи и значения соответственно. Операторы:
Набор операторов в Perl Очень широк,многие из них прямые аналоги имеющихся в других языках,например if,for,while;но есть и значительные улучшения имеюшихся и конечно новые.
Тот же самый оператор if имеет две формы (как когда удобнее): В пару к оператору if имеется оператор unless : означающий if с отрицанием: Также в пару while существует until
синтаксис оператора for полностью аналогичен C: новшеством(и приятным) является foreach позволяющий пройтись по всем элементам массива,присваивая по очереди его элементы какой-то переменной, его синтаксис такой:
Последний пример особенно важен для упрощения вашего тяжкого труда програмиста и демонтстрирует интересную особенность Perl-переменную по умолчанию $_: в оргомном количестве операторов и функций при опускании аргумента она подразумевается по умолчанию. Она также по умолчанию сопоставляется с регулярным выражением: как видите затраты труда значительно сокращаются,благодаря этому маленькому трюку.

Регулярные выражения.
регулярное выражение записывается между двух слэшей /рег_выр/ это самый простой пример применения регулярного выражения а теперь посложнее вот тут в табличке (из того что я помню наизусть):

Символ Значение Пример применения
. Соответствует любому символу print if /ab.c/;
[мн-во симв] Соответствует любому символу из данного мн-ва /[abc]d/;#соответствует ad,bd,cd
[^мн-во] Отрицание мн-ва символов /[^xyz]/;#
(. ) Группировка элементов(и также запоминание в переменных $1 $2 $3 . ) /(xyz)*/
/([abc].[^xy]qwerty)/
(..|..|..) Одна из альтернатив
* повторение образца 0 или более раз /.*/;#соответствует всему
? Повторение 0 или 1 раз /(http:\/\/)?.*\.cgi/
+ Повторение 1 или более раз
повторение от n до m раз
повторение точно n раз
повторение n и более раз
Спец символы:
\t \r \n . Управляющие символы:табуляции,возврат каретки,перевод строки.
\d Соответствует цифре,Аналог [0-9]
\D Соответствует нецифровому симсволу,аналог[^0-9]
\w Соответствует букве
\W Соответствует небуквеному символу
\s Соответствует пробельным символам(пробелы,табуляции,новые строки..)
\S Соответствует непробельному символу
\b Соответствует границе слова $test1=»this is test»;
$test2=»wise»;
if($test1=

/\bis\b/)#нет

\B Соответствует не границе слова /\Bis\B/ соответсвует ‘wise’ но не ‘is’

Для того чтоб поместить в регулярное выражение любой специальный символ,поставьте реред ним обратный слэш Заставить Perl игнорировать регистр можно поставив i после регулярного выражени
Полезные функции.
В Perl очень много различных функций ,как говорится на все случаи жизни,все о них конечно не опишу,но обо многих. Начну с тех,которые больше относятся к операторам. Операция замены s/рег.выражение/строка/ игнорировать регистр — опция i глобальная(по всей строке) замена -опция g; Пример: Очень полезная опция у s/// e -она означает что вторая строка не строка а выражение, результат которого и будет подставлен. Например,у вас есть файл в котором все записи о возрасте через год надо менять или более показательным примером послужит функция urldecode,которая будет встречатс в каждой вашей программе,обрабатывающей формы: Также важным удобством в Perl являются операции для работы с файлами для выполнения схожих функций в других языках приходиться проделывать огромную массу работы. Аргументами могут быть как Файловые переменные,так и строки,представляющие имя файла.

Операция Описание Пример использоввания
-r Доступен для чтения unless(-r «myfile»)
-w Доступен для записи
-x Для исполнения
-o Принадлежит пользователю if(-o «index.htm»)
-R Доступен для чтения реальным
пользователем,а не только «эффективным».
Имеет значения для set-uid -скриптов
if(-r FILE)>
-W Доступен для записи реальным пользователем
-X Доступен для исполнения реальным пользователем
-O Принадлежит реальному пользователю
-e Файл или каталог Существует unless(-e $htmlfile)<
open(HTML,»>$htmlfile»);
print HTMLFILE » «;
close(HTMLFILE);
>
-z Существует,но имеет нулевую длину if(-z ‘tmpfile’)
-s Размер файла в байтах system(«rar m -m5 archive.rar $myfile») if -s $myfile > 1000;
-f Файл существует и является простым файлом
-d Файл существует и является каталогом if(-d ‘public_html’)
-l Символической ссылкой
-p Каналом FIFO
-u Имеет бит установки пользователя
-g Имеет бит установки группы
-k Установлен sticky-бит
-t Является терминальным устройством
-M Время с последнего изменения (в днях) while(defiled($file=glob(‘*’))) <
if(-M $file >= 7.0) <
unlink($file);#удаляем слишком старые файлы
>
>
-A Время последнего доступа(в днях) if(-A «$ENV<'HOME'>/public_html/index.html»
избавиться от символа новой строки на конце поможет функция chomp, ведь этот символ может помешаться например в имени файла или при выводе на экран Если также подставить списочную переменную,то получим список строк файла от текущей строки и до конца бинарный файл можно читать и писать функциями sysread и syswrite:
sysread(ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт)
syswrite(ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт)
функции split и join: @Список=split(/рег.выр/,$скаляр);
$скаляр=join(строка,@Список);
Встроеные функции Perl можно вызывать со скобками или без (как вам удобно), скобки программисты указывают или для красоты,или чаще,что устранить возможную неоднозначность в выраженнии: Надеюсь что я вас позабавил примерами функций ;).

Примеры применения Perl для различных нужд.
Следующая программа переводит текстовый файл в формат HTML (вспомните сколько хлопот вам доставит отлов во всем файле ‘ ‘ и ‘&’ чтоб заменить их на &tl; , > и & а как неплохо чтоб автоматически все http://www. превратились в http://www. ) Более подробную информацию о Perl вы можете получить по адресам:
http://www.perl.com
http://www.metronet.com/0/perlinfo/perl5/manual/perl.html
http://www.ActiveWare.com/

Заголовки запросов и ответов

Даже если вы и знаете кое-что о HTTP все равно не лишне будет вспомнить о том как это все работает тем более на эту информацию придется ориентироваться при написании CGI скриптов.
Этапы соедирения.
Первый этап это когда HTTP -клиент(браузер) соединяется с сервером.для этого он использует протокол TCP/IP соединение происходит к известному клиенту TCP-порту (80 -номер порта HTTP) (другие сервисы сидят на других портах ,например FTP и SMTP на 21 и 25)
Вторым этапом идет запрос клиента:клиент передает заголовок запроса и возможно(в зависимости от метода) тело сообщения запроса.В заголовке обязательно указывается метод ,URI,и версия HTTP,и может быть еще несколько необязательных полей
Третий этап -ответ сервера,который опять таки состоит из заголовка,в котором сервер указывает версию HTTP и код статуса, который может говорить о успешном или неуспешном результате и его причинах.Далее идет тело ответа.
Четвертым этапом происходит разрыв TCP/IP соединения.
HTTP -запрос.
Запрос состоит из Строки запроса(она обязательна) и остальных полей. Синтаксис строки :МЕТОД URI HTTP/версия
где -пробел , -переход на новую строку
Методы HTTP.
GET
Самый часто применяемый метод,в протоколе HTTP/0.9 был единственным методом,и применяется для извлечения информации по заданому URI Может быть условным если в заголовке указано поле If-Modified-Since:

HEAD
Почти идентичен GET но отличается тем что сервер не возвращает тело обьекта а только его заголовок (метаинформацию) программы могут применять его для проверки гиперссылок на правильность,доступность и изменения.

POST
передает данные для обработки их программой ,указаной в URI сдесь обязательно указывается поле Content-Length:

Сушествуют и другие ,реже применяемые методы,например PUT -для сохранения передавемых данных в указаном URI и DELETE для удаления ресурса.

Поля заголовка запроса.
После строки запроса идут поля заголовка запроса. Поля общего(general-header) заголовка (он общий как для запросов так и для ответов):
Date:
Указывает дату запроса,например:
Date: Sun, 20 Nov 1994 08:12:31 GMT

MIME-version:
Указывает версию MIME (по умолчанию 1.0)
MIME-version: 1.0

Pragma:
Содержит указания для таких промежуточных агентов как прокси и шлюзы,
Pragma: no-cache

Поля относящиеся к запросу(Request-Header):
Authorization:
Содержит информацию аутентификации
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

From:
Браузер может посылать адрес пользователя серверу
From: quake@doom.ru

If-Modified-Since:
используется при методе GET ресурс возвращается ,если он был изменен с указаного момента, может использоваться при кешировании.
If-Modified-Since:Mon 15 Jul 1997 00:15:24 GMT

Referer:
Содержит URL предшествующего ресурса.
Referer: http://www.uic.nnov.ru/

User-Agent:
Програмное обеспечение клиента.
User-Agent: Mozilla/3.0

Заголовок информации сообщения (Entity-Header) применяется как в запросах так и в ответах (при этом некоторые поля только в ответах):
Allow: (в ответе сервера)
Список методов,поддерживаемых ресурсом.
Allow: GET, HEAD

Content-Encoding:
идентифицирует метод кодировки,которым был закодирован ресурс
Content-Encoding: x-gzip

Content-Length:
Длина тела сообщения
Content-Length: 102

Content-Type:
Содержит тип ресурса(MIME),для текстовых еще и кодировку символов(необязательно)
Content-Type: text/html; charset=windows-1251

Expires: (в ответе сервера)
Дата окончания действия ресурса,применяется в кешировании для запрета кеширования устаревших ресурсов (в ответе)
Expires: Tue, 24 Sep 1998 23:00:15 GMT

Last-Modified: (в ответе сервера)
Время последнего обновления ресурса
Last-Modified: Tue, 23 sep 1998 13:48:40 GMT

Другие поля:
Поля Accept: указывают серверу выдавать только указаные форматы данных,которые клиент может распознать.
Accept: text/html
Accept: text/plain
Accept: image/gif

Поле Host: служит для того , чтобы указать, к какому хосту идет обращение. Данное поле не входит в число обязательных. Однако оно является необходимым в тех случаях, когда одному физическому серверу соответствует несколько виртуальных хостов. В этом поле тогда указывается какой из виртуальных хостов имеется в виду.
Host: www.nnov.city.ru

Примеры запросов: Ответ HTTP-сервера.
Ответ идет от сервера.Состоит он из строки состояния и затем поля ответа Общий заголовок(General-Header) и заголовок тела сообщения (Entity-Header),которые уже описаны при обсуждении запроса. и еще идет заголовок ответа(Response-Header).
Строка состояния имеет следующий формат:
HTTP/version Status-Code Status-Phrase
где HTTP/version версия,Status-Code -3х значный код,и Status-Phrase текстовая фраза, поясняющая код ,пример: HTTP/1.0 200 Ok
,200 -код означающий успешную обработку запроса,что и поясняет «Ok» Заголовок ответа состоит из полей:
Location:
Содержит URI ресурса,может быть использован для переключения клиента в другое место, если например ресурс был перемещен в другое место или на другой сервер.
Location: http://www.uic.nnov.ru/newlocation/index.html

Server:
Информация о програмном обеспечении сервера
Server: Apache/1.1

WWW-Autenticate:
Параметры аутентификации.
WWW-Autenticate: Basic realm=»doomsday»

Коды ответов HTTP.

Код статуса Значение
200 OK
201 Успешная команда POST
202 Запрос принят
203 Запрос GET или HEAD выполнен
204 Запрос выполнен но нет содержимого
300 Ресурс обнаружен в нескольких местах
301 Ресурс удален навсегда
302 Ресурс отсутствует временно
304 Ресурс был изменен
400 Плохой запрос от клиента
401 Неавторизованый запрос
402 Необходима оплата за ресурс
403 Доступ Запрещен
404 Ресурс не найден
405 Метод не применим для данного ресурса
406 Недопустимый тип ресурса
410 Ресурс Недоступен
500 Внутренняя ошибка сервера
(это по вашу душу,юные CGI-программисты ;( )
501 Метод не выполнен
502 Неисправный шлюз либо перегруз сервера
503 Сервер недоступен/тайм-аут шлюза
504 Вторичный шлюз/тай-аут сервера

Более подробное описание всех кодов можно найти в RFC-1945
Несколько примеров:
CGI-заголовок.
В том случае когда запрашиваемый URI есть CGI-скрипт сервер базируясь на данных запроса создает среду переменных CGI и передает управление скрипту скрипт должен выдать CGI-заголовок,после которого и идет тело ответа,сгенерированое скриптом.
Заголовок (CGI-Header) состоит из полей:
Content-Type:
Должно обязательно присутствовать,если есть тело.
Content-Type: text/html

Location:
Содержит URL ресурса на который скрипт перенаправляет запрос.Как правило,если присутствует это поле больше ничего не указывается.
Location: http://www.idsoftware.com/index.html

Status:
Позволяет CGI скрипту вернуть статус обработки,если это поле не задано,то сервер подразумевает
Status: 404 Not found

На базе этой информации сервер и формирует окончательный заголовок,который и передается клиенту.
Примеры: nph-скрипты.
Иногда возникает необходимость чтобы CGI -скрипт сам отвечал напрямую клиенту, минуя разбор заголовка.Это во-первых уменьшает нагрузку на сервер,и во вторых, что самое главное такой прямой ответ клиенту позволяет скрипту полностью контролировать транзакцию.Для этого существуют nph-скрипты(Not Parse Header) ,имя скрипта должно начинатьс с префикса «nph-« ,Например «nph-animate.cgi» .Такие скрипты сами формируют HTTP-ответ клиенту,что полезно при анимации:
Этот пример вам выдаст анимацию ,составленую из нескольких .gif -файлов.Если же вы получили вместо анимации сообщение об ошибках,то вам следует,может быть перейти к следующей главе, которая поведает вам о правах доступа- того,без чего Unix не был бы Unixом.

Права Доступа

Я бы ни за что не написал этот раздел,если бы он не был так важен.Сидя в пределах своей домашней директории и занимаясь только тем,что качаете с Инета всякую херню,вы возможно и не задавались некоторыми вопросами. а зря. Ведь немного надо,чтоб попортить нервы начинающему CGI -програмисту.
Одна из таких вещей это права доступа.
Начнем с того ,что в системе Unix каждый пользователь имеет свой идентификатор- число,уникально идентифицирующее его в этой системе.(Мой логин paaa а ему соответсвует число 1818).Это число внутреннее для операционной системы,для пользования оно представлено как логин,который и соответствует пользователю.
Только не надо думать о пользователе,как о конкретном человеке сидящим за клавиатурой, пользователем может быть и какой-нибудь процесс.Важно отметить что пользователь-это определенна область прав доступа,которая ему соответствует.(Вы например не можете обычно писать и удалять файлы из каталога другого пользователя). Это и дает возможность стабильной работы всей системы.
Итак есть идентификатор пользователя.Также имеется идентификатор группы.
Группа служит для выделения пользователей по группам. Например у пользователей группы users (Обычные пользователи) не такие права как у группы wheels (административная группа).
Каждый процесс который вами запущен(Будь то Netscape,терминал,или текстовый редактор)получают ваши идентификаторы пользователя и группы. таким образом исполняются от вашего имени.
Теперь рассмотрим повнимательней файловую систему.В Unix с файлом связано много характеристик. Во-первых в системе нет «ничьих» файлов ,все файлы имеют владельца-пользователя и владельца-группу. Любой файл который вы создаете автоматически получает ваш идентификатор.По этому система очень легко отслеживает, чьи это файлы и каталоги.
Следующее новшество по сравнению с DOS это права доступа к файлу.Их может сменить только тот пользователь которому принадлежит файл,или супервизор.(Это в отличии от DOS где каждая дрянь типа вируса может снять атрибут readonly читать и писать все файлы ;()
Права доступа задаются обычно числом в восьмеричной записи и разбиты на 3 части по 3 бита: Каждая часть задает права доступа для конкретной группы:

1я -права доступа для пользователя,которому принадлежит файл
2я -для группы которой принадлежит файл
3я -для всех остальных

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

Бит Описание
8 Право на чтение для пользователя
7 Право на запись для пользователя
6 Право на исполнение для пользователя
5 Право на чтение для группы
4 Право на запись для группы
3 Право на исполнение для группы
2 Право на чтение для всех остальных
1 Право на запись для всех остальных
Право на исполнение для всех остальных

Изменяются права командой chmod,ее синтаксис такой:
chmod [u|g|o]<+|-> file
chmod number file
,где uuser,ggroup,oother,rread,wwrite,x-execute;-удалить,+-установить
Примеры:
chmod +r file.txt #разрешает всем право на чтения файла
chmod u+w file.txt #устанавливает для владельца файла право на запись в него
chmod +x gbook.cgi #право на исполнение для всех,как для ползователя,группы,и для других
chmod 0777 cgi-bin #Разрешает самые широкие права доступа для cgi-bin

Приоткрытии файла программой,операционная система сравнивает идентификатор пользователя с идентификатором пользователя владельца файла, если они равны,то действуют права пользователя,если не равны то сравниваются идентификаторы группы,если и они не равны,то действуют права доступа для остальных остальных.В том случае если у процесса нет достаточных прав,система возвращает ошибку. Следует заметить ,что для супервизора root права доступа не проверяются.
Можно выполнить скрипт,только если есть права на его исполнение. Вот почему следует давать chmod +x *.cgi иначе ваши скрипты станут просто недоступными. Но и это еще не все.
Ваш скрипт может обращатся к вашим файлам (например ведет базу данных гостевой книги). Все выглядит нормально,но только ничего не работает,файл в который вы намеревались писать,
не открывается,знакомая проблема ;(( ?.Так вот чтобы вы не мучались в догадках Ваш скрипт не может получить доступ к вашим файлам,потому что он выполняется не вами (не с вашим идентификатором), а от имени nobody (непривелигированый пользователь).Это мера предосторожности направлена на то, чтоб скрипты ,взбесившись из-за неправильно переданых параметров(или вообще от глюков) не могли ничего повредить ценного и важного на сервере.
Поэтому к тем файлам,к которым скрипт по смыслу должен обращатся нужно присвоить самые широкие права доступа 0777
Например в случае гостевой книги chmod 0777 guestbook.dat
Если также важно чтоб скрипты могли заводить новые файлы в cgi-bin то надо дать также права на это chmod 0777 cgi-bin
Если вы видите что ваш скрипт не может обратится к какому-то файлу,то это в 99% случаев из-за вашей забывчивости.
На самый крайний случай воспользуйтесь setuid-скриптами (к этому делу ,если вы на это решились,отнеситесь ОЧЕНЬ серьезно,так как целые тома по безопасности в Unix посвящены именно setuid-программам). Хочу сразу предупредить ,сам я таких не так уж много писал,да и вам не особенно советую. Но для общего как говорится развития,имейте в виду следующую информацыю.
Кроме указания прав доступа,существуют специальные биты у файла.Это биты установки пользователя и группы. Когда процесс выполняется(простой процесс) то его реальный и эффективный идентификаторы пользователей совпадают,идентификаторы групп тоже. На самом деле значение имеют как раз эффективные значения пользователя и группы,они учавствуют в сравнении прав доступа. Нельзя ли их как-то изменить,когда уж совсем нужда заставит? Можно! .На этот вопрос дают ответ программы с установленым битом пользователя.Когда система запускает такую программу,она присваивает новому процессу не идентификатор того пользователя,что запустил ее, а идентификатор пользователя-владельца исполняемого файла.
Самый классический пример setuid-программ это программа passwd ,предназначеная для смены пароля пользователя. Такие данные как пароль и прочие характеристики пользователей хранятся в специальном файле,который имеет огромное значение при входе в систему. Так как это системный файл,то открыть к нему доступ на запись всем-значит подвергнуть ВСЮ систему риску,ведь любое неправильное изменение его повлечет катастрофические последствия(в конце концов бывает просто хулиганство). Поэтому доступ к этому файлу закрыт для всех пользователей.А что если надо сменить пароль? Запускаем программу passwd! Если глянуть на ее аттрибуты ,то видно что она принадлежит root -супервизору, и еще имеет установленый бит setuid. Так корректно обходится эта проблема.
Если вы все-же решили попытаться ,то знайте ,что сделать программу setuid можно
коммандой : chmod +s myprogramm

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

Генерация ответа

Большую часть того что нужно знать о генерации ответа,я сказал в разделе Заголовки запросов и ответов.Нет,не угадали! Я не буду сдесь говорить о всяком дизайне того что вы выдаете.Этому вы успели напрактиковатся на HTML -страничках.
Я поговорю о MIME (Multipurpose Internet Mail Extension).И о разных браузерах.
Стандарт MIME появился в электронной почте (e-mail) потому что остро стала проблемма пересылки по e-mail различных данных в различных форматах.Так как HTTP тоже работает с различными типами данных то поэтому тоже использует MIME для своих нужд. Типы MIME состоят из Типа и подтипа (например text/plain,где text-указывает на наличие текстового содержимого,а plain-уточняет его как простой текст) приведеный ниже список (он далеко не полн,типов MIME огромное количество) описывает некоторые часто встречающиеся типы.: text/html text/plain text/richtext image/gif image/jpeg image/tiff audio/basic audio/32kadpcm audio/ video/mpeg video/quicktime multipart/mixed multipart/alternate multipart/ application/octet-stream application/msword application/postscript message/digest
Информация о MIME больше возможно пригодится вам в том случае если вы собираетесь работать из ваших скриптов с электронной почтой,но и для WWW она не повредит. Особенно знание Content-Type:
Content-Type:
Состоит из типа и подтипа типы могут быть как стандартные так и экспериментальные начинающиеся с префикса ‘x-‘:

text
Текстовые данные.Первым подтипом который включен сюда это plain,что значит простой текст. сюда же включен самый ходовой формат html .У типа text как и у многих типов могут быть параметры,главным из них является charset он как раз и указывает на раскладку символов, которая применена в тексте, так что если вы хотите указать браузеру какую раскладку применять, то просто укажите charset:
Content-Type: text/plain; charset=us-ascii
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=koi8-r

multipart
Данные которые могут состоять из нескольких частей,различных типов данных.Поэтому параметром multipart служит boundary, позволяюший указать разделитель.Каждый фрагмент в многочастевом сообщении имеет свой Content-Type: (Он может быть также multipart,т.е. допускаются вложеные multipart,главное чтоб boundary были разными).В электронной почте применяется больше multipart/mixed (основной подтип) и multipart/alternative (Он отличается тем что показывается одна из альтернатив,например сообщение шлется в простом и HTMLом форматах,и почтовая программа показывает либо часть,которую она способна отобразить). В WWW -програмировании распостранен x-mixed-replace ,который означает что следующая часть должна заменить предыдущую после подгрузки, что применяется для анимации(см.Пример с анимацией).
Теперь о разделителе,его надо выбирать так,чтоб он не встретился где-то в данных (т.е. что-то вроде «diUr344rnmvforgefvrg923rghyj2»).Когда вы задали разделитель,например boundary=»boundary» то когда закончилась одна часть,вы должны выдать строку —boundary,последн часть —boundary—,причем эти разделители должны быть на отдельной строке,а не сливаться с текстом:
Пример:

message
Представляет инкапсулированое почтовое сообщение.Используется в e-mail ,а не в WWW.


image
Некоторое Графическое изображение.(чаще всего image/gif и image/jpeg)

application
бинарные данные какого-нибудь приложения.В том случае если данное приложение может быть запущено,Браузер запускает его.Например при поступлении данных application/msword Браузер спросит,нужно ли запустить Word для просмотра досумента.При отсутствии нужного приложения браузер спросит в каком файле сохранить данные.Подтип octet-stream как раз и означает поток байт информации,который и используется по умолчанию.(К сожалению не все так гладко,известен глюк в Netscape Navigator‘е который вместо того чтоб сохранить application/octet-stream пытается его показать как text/plain что если это сгенерировано из CGI,ни к чему хорошему не приводит ;(()
Что касается application ,то Вы можете тут смело извращатся,используя x- типы данных,
Например application/x-fuck-to-netscape-navigator. ;)))))
Часто используемый параметр name позволяет указать имя файла.Например:
Content-Type: application/msword; name=»readme.doc»
Что полезно при полученнии файлов через HTTP,причем этот параметр может применятся и для других типов таких image или audio ,Например:
Content-Type: image/gif; name=»myfoto.gif»

Content-Transfer-Encoding:
Применяется больше в системе электронной почты и обозначает метод кодирования, которым были закодированы данные при передаче сообщения.Например:
7bit 8bit quoted-printable base64 binary x-типы
MIME-Version:
Указывает версию MIME .

Теперь поговорим о разных браузерах вы знаете что браузеры бывают разные,разных версий на разных платформах, поддерживают и не разные тэги и глюки у них тоже разные. ;((( .
Это могло попортить много нервов WEB-дизайнерам и конечно же нам ,CGI-програмистам. Профессионально написаный сайт от просто хорошего отличается тем что хорошо выглядит Не только на экране того браузера,которым пользуется сам его автор,а на других тоже.
Если вы используете JavaScript для своих страничек,то вы уже наверно использовали (или хотя бы вам в голову приходила мысль использовать)свойства navigator.AppName navigator.AppCodeName navigator.appVersion navigator.userAgent:
Ну не волнуйтесь вы так ,мы CGI-программисты не в самых худших условиях на этот счет. Вспомните о том что браузер сам при запросе посылает вам данные о себе и о своей версии. И делает он это для того,чтобы эту информацию можно было учесть.
В запросе он указывает User-Agent: которое и попадает на сервере в переменную среды HTTP_USER_AGENT ,которую и можно использовать.
Например если в ней содержится Mozilla/3.01Gold (Win95;I) то значит вы имеете дело с Netscape (Mozilla-кодовое название Netscape Navigator‘а),версии 3.01Gold и далее после имени и версии может следовать необязательная информация ,например как в приведеном примере о платформе Win95 и о том является ли версия U -для США (USA) или I -международной(International). Напомню,что такая информация необязательна.(То есть если браузер послал информацию User-Agent: то гарантировано расчитывать вы можете только на Название/Версия).
Ну вот я слишком много развел демагогии,пора переходить к практическим примерам.
Допустим ваш скрипт генерирует какие-то тэги,которые слишком старые браузеры не поддерживают,причем без них не обойдешся,они составляют всю ‘изюминку’ сайта.
Ну уже почувствовали,насколько это здорово.А вот еще примерчик.Это из разряда того, что тэги бывают разные.Например в Explorer есть тэг BGSOUND предназначеный для проигрывани музыки на страничке.(В Netscape этого тега нет,и поэтому для втыкания музыки приходится использовать подключаемые модули plugin).Мутится с этими Плугинами Вам в облом,а хочется побаловать человека хорошей музыкой,если браузер позволяет. Ну вот вы уже можете управлять этим процессом.Только не забывайте,что если вы не получили информацию о клиенте(так может быть,если например ваш скрипт вызвал какая-нибудь поисковая машина) то не в этом случае не надо делать никаких предположений,а просто пусть ваш скрипт продолжает делать то что должен был делать.

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

Обработка Форм

Ну вот ,вы уже знаете достаточно,кое в чем уже успели приобрести опыт, пришло время перейти к очень важной теме — обработке форм. При всей простоте (кажушейся) это едва ли не самое главное предназначение всего стандарта CGI . Куда бы вы не зашли на любой уважающий себя сайт,везде вы встретите формы, которые вам предложат заполнить.В этом деле можно положится только на CGI, так как Java и JavaScript ,выполняющиеся на страничке у клиента не имеют доступа к серверу,на котором находится сайт.
Коротко вспомним о том что происходит при рассматриваемом процессе поближе,так сказать на трезвую голову ;). Итак браузер требует у сервера определенный URL (это может быть как простой документ,так и сгенерированый CGI) в этом документе может содержаться форма.Отображая такой документ браузер также выводит элементы формы (кнопки, поля ввода, поля ввода пароля, переключатели, радио-кнопки, списки, текстовые области,скрытые поля). И со всем этим добром пользователь может взаимодействовать.К форме естественно имеет доступ и встроеный язык программирования JavaScript -он может как использовать форму для своих нужд,не передавая CGI,так и помогать пользователю в заполнении формы.
После того,как пользователь заполнил форму он нажимат кнопку Submit которая говорит, что форму надо отправить на сервер. Браузер собирает все имена и значения элементов формы ,кодирует их методом urlencode и в зависимости от указаного в тэге FORM метода вызывает GET или POST с указаным URL,передавая ему данные. На сервере CGI-скрипту это попадает (в зависимости от метода) либо в переменную QUERY_STRING либо на STDIN.Скрипт может проверить данные ,занести их в какую нибудь базу данных,может как yahoo выполнить какой-нибудь поиск, может что-нибудь вычислить. да мало ли что он может,все зависит только от нашей фантазии. В конце концов скрипт выдает браузеру ответ,который он и отображает.В этом ответе может содержаться все что вашей душе угодно от сообщения об удачном или неправильном запросе до таких ответов,по сравнению с которыми yahoo и altavista подвиснут от зависти, главное чтоб вам и тем кто посещает ваш сайт это нравилось.;)

Ну а теперь немного о синтаксисе элементов форм ,их описании и самое главное особенностях при обработке CGI-скриптом.
Итак немного экскурс в HTML:
FORM
Атрибуты:
action
как раз и задает тот URL,который будет и обрабатывать форму, если он опущен,то текущий URL документа(а он-то может быть сгенерирован нашим скриптом).
method
задает метод GET или POST
enctype
обычно не задается,для форм он application/x-www-form-urlencoded -по умолчанию, и поддерживается всеми CGI скриптами.Но если вы уж очень хотите чтобы браузер послал вам данные в другом формате (например text/plain) то можете указать этот тип кодировки,только потом не жалуйтесь,что ваш скрипт не может разделить поля,или вообще начинает глючить когда пользователь ввел какой-то спецсимвол.
name
Задается для JavaScript,чтоб обращатся к форме по имени,а не по номеру. Для CGI не играет ни какой роли,так как внутреннее для браузера.
target
Может Определять в какой фрейм отправить полученую информацию.Имеет значение во фреймосодержащих документах.Прозрачен для CGI обработки данных.
onSubmit
Определяет JavaScript -обработчик активизации формы.Применяется для проверки JavaScript‘ом правильности заполнения.Опять таки прозрачен для CGI.
Пример типичной формы: Форма может содержать элементы.Элементы имеют имена,которые используются дл кодирования пар имя=значение.Некоторые Элементы не передаются CGI,а используются JavaScript для управления,например кнопки.Некоторые поля передаются только в тех случаях, когда в них что-то выбрано,например списки и переключатели.Остальные поля передаются всегда, даже когда они пустые.
Например: Допустим вы ввели имя lesha и адрес paaa@uic.nnov.ru,при этом выбрали переключатель После нажатия кнопки будет отправлен вот такой запрос:
http://www.doom/cgi-bin/test.cgi?Name=lesha&Email=paaa@uic.nnov.ru&doomer=Yes
Если же вы не выбрали переключатель,то запрос будет таким:
http://www.doom/cgi-bin/test.cgi?Name=lesha&Email=paaa@uic.nnov.ru
,как видите элемент doomer не вошел в строку запроса
Теперь попробуйте оставить поля редактирования пустыми:
http://www.doom/cgi-bin/test.cgi?Name=&Email=
Эти элементы (Name и Email) присутствуют и сообщают что они пустые.

Кнопка(button)

В форме изображается кнопка,при нажатии которой вызывается JavaScript-обработчик заданый атрибутом onClick ,атрибут name служит для JavaScript-именования кнопки а не дл передачи CGI.Так как значение кнопки не передается CGI, value задает Текст,изображаемый на кнопке.

Submit

Кнопка,предназначеная для передачи формы.Опять же,сама не передается,а служит только для управления. текст на ней задается атрибутом value.
Reset

Кнопка очистки формы.При ее нажатиивсем измененым элементам возвращается значение по умолчанию.
Поле ввода(text)

Применяется очень часто,поэтому тип «text» служит для INPUT по умолчанию,его не надо каждый раз указывать.Имя поля,задаваемое name является обязательным для CGI (в отличии от JavaScript,где элементы формы можно индексировать по номерам,а имена для удобства и читабельности кода служат).Можно задать значение по умолчанию атрибутом value,которое будет после загрузки докумета.атрибут size позволяет задать размер поля.Также может содержать обработчики onBlur,onChange,onFocus,onSelect.
Текстовая Область(textarea)
Область многострочного редактирования.Размеры в строках и столбцах задаютс атрибутами rows и cols.Значения атрибута wrap «hard» и «soft» -означают соответственно мягкую или жесткую разбивку на строки (в большинстве случаев ето не существенно). На что следует действительно обратить внимание так это на символ,используемый для указания перехода на новую строку. В Windows это ‘\r\n’ а в Unix ‘\n’,так что если это для вас существенно,то приводите преобразование,например так:
$my_text =

s/\r\n/\n/g;
Поле ввода пароля(password)

Очень похоже на поле ввода,отличается тем что вместо символов в нем отображаютс символы ‘*’.Служит для ввода пользователем пароля.
Скрытое поле(hidden)

Поле не отображаемое на экране.Но оно имеет имя и значение и следовательно передается в форму. Служит для того (и очень часто програмисты его применяют) чтоб передавать скрипту какую нибудь информацию.Например,если ваш скрипт обрабатывает несколько форм разных типов,то в скрытом поле каждой формы можно указать с какой формой конкретно вы имеете дело. Так как это ваша внутренняя кухня то нечего пользователю мозолить глаза этой информацией.
Переключатель(checkbox)
Text
В отличии от кнопки,атрибут value сдесь не задает на надпись на переключателе,а его значение(внутреннее).Поэтому если надо что-то подписать,пишите рядом в ним. Может быть сразу выбраным если указан атрибут checked .Если value не указано то значение по умолчанию «on» .Передается только в том случае,когда выбран.
Радио-кнопка(radio)
Text
В отличие от checkbox может быть несколько радиокнопок с одинаковым параметром name ,но с разными value,из них передается только та,что выбрана.Одна из них может быть изначально выбрана по умолчанию checked.Например:
Список(select)
Задает список,позволяющий выбрать одну (или несколько) опций из списка. Если атрибут multiple не указан,то создается простой выпадающий список,в котором можно выбрать только одну из опций.Его значение всегда передается,т.к. всегда хоть одно выбрано. Если указан атрибут multiple,то во первых можно указать размер видимой части списка атрибутом size (Если опций больше появится скролинг).Во вторых передаются только выбраные опции ,т.е.Он может передатся несколько раз ?SelectName=opt1&SelectName=opt2&SelectName=opt9 если выбраны скажем несколько опций.А может и не разу,если ничего не выбрано из списка. Можно задавать обработчики onBlur,onChange,onFocus.
Небольшая Помощь JavaScript
Для CGI-програмиста конечно JavaScript -это иной мир,вы можете спокойно пропустить этот абзац,если вы не знаете JavaScript,так как написаное в нем к CGI не относится, а скорей к самим формам и дизайну сайта.Я скажу пару слов о том как JavaScript может оказать посильную помощь в проверке правильности заполнения форм.Все проверки конечно можно и нужно делать на сервере,но когда имеешь дело с рассеяным пользователем, то для него заполнение простой формы превратится в мучение.Поясню на примере,в форме есть какие-то обязательные поля,например имя.Если пользователь забыл его указать то скрипт скажет ему об этом в сообщении он исправит это, допустим что-нибудь еще не так ввел . Только на передачу данных по сети может уходить масса времени.А на обработку на локальной машине-доли секуды.
Вот Например как это можно применить JavaScript для предварительного контроля правильности. Допустим простейшая форма содержит имя и возраст.Имя не должно быть пустым, а возраст должен состоять из цифр. Ну вот ,на этом можно закончить это краткое введение в HTMLые формы.
Итак,У нас на входе скрипта данные формы,закодированые методом urlencode Положеные в Переменную QUERY_STRING или подаваемые на STDIN.Мы должны вопервых их получить. Вот,мы уже считали наш запрос в переменную $query.Теперь пришло самое время ее обработать. Мы знаем что поля разделены символом ‘&’ значит используем его в качестве разделителя функции split: Вот разделили,а теперь организуем цикл foreach по полученым полям @formfields Сдесь выражение в регулярном выражении в круглых скобках (.*) после знака ‘=’,запоминаетс в скалярную переменную $1 ,которая затем и декодируется нашей старой и знакомой функцией urldecode (я предупреждал,что она будет почти в каждой вашей CGI-программе) Так мы проходим по всем полям,которые нам переданы.Это стандартный подход,он годится в качестве шаблона.У вас может возникнуть вопрос,а что делать если вам переданы данные от списка у которого задана возможность выбора нескольких элементов и данные поступают в таком виде: Sel=opt1&Sel=opt2&Sel=opt9. Тут тоже нет никаких проблем,просто запихиваем эти поступающие значения в массив. И потом спокойно оперируем с Полученым Массивом @Sel.
На этом можно так сказать заканчивается шаблонная часть скрипта и начинается содержательная, которая зависит только от вашей фантазии.
Вы можете сколько угодно анализировать полученые значения,обращатся при этом к различным файлам .Если вы к этому приложите фантазию,то кто знает что получится.
А Пока Ради примера я вам напишу скрипт,который ведет социологическое исследование насчет курения и отношения к нему.Может он слишком массивен для данного пособия, но зато он наглядно показывает как достаточно простыми средствами можно проводить социологические исследования. А вот скрипт для его обработки:

Изображения ismap

Анимация

Когда говорят о каком-то популярном сайте,то частенько к преимуществам относят и анимацию. Действительно,когда изображение изменяется (и особенно к месту ;)),то это смотритс и пользователю нравится.
Говоря об анимации нужно сразу отметить что нет лучшего способа. Анимацию можно сделать ДЕСЯТКАМИ Способов,каждый хорош в своей области применения. Я перечислю только некоторые из них,которые чаще всего применяются:
Самый простой,но наименее функциональный способ это GIF с анимацией.
Потом можно воткнуть анимационный файл MPEG или AVI они более отражают суть анимации, но имеют недостаток,что для проигрывания их на некоторых браузерах нужны специальные подключаемые модули.К тому же они не интерактивны.
Можно реализовать анимацию в рамках Java-апплета,когда апплет находясь на страничке сам перерисовывается со временем.
Таким же интерактивным средством служит обращение к массиву document.images[] из JavaScript.Достоинство-помимо интерактивности,полная интегрированость с HTML -станичкой.Но может как и предыдущий использоваться только с относительно новыми браузерами,которые поддерживают Java и JavaScript.

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

Несколько советов по отладке

CGI-программы -не самые простые в отладке,по сложности отладки они способны сравнится лишь с отладкой драйверов. Вся сложность заключается в том,что скрипт выполняется не как обычная программа. Он выполняется в специальной среде сервера,которая создается при клиентском запросе, к тому же он исполняется не из под вашего аккаунта,а на непривилегированом уровне.
Если скрипт не исполняется потому,что вы допустили синтаксические ошибки,то самих этих ошибок вы не увидите,на экране будет только из-за чего она произошла вы можете только гадать. Также если вы забыли задать к какому-то файлу нужные права доступа ,то тоже будет трудно выяснить что же произошло и в чем причина ошибки (если конечно к этому вы не готовы).
Ну вот ,хватит вас пугать,тем более что нас не запугаешь ;) !
Приступим к отладке.Я вам опишу достаточно примитивные меры,которыми я сам пользуюсь.
Начнем с того что у нас есть скрипт test.cgi мы уже сделали его исполняемым chmod +x test.cgi Простейший способ проверить его на ошибки это команда Ключ -c говорит Perl что надо только проверить синтаксис.Все сообщения об ошибках вы можете видеть и подправить.Более тяжелый случай состоит в том когда Perl встроен в Web -Сервер, причем версии разные.Как у до недавнего времени было на uic‘е ;(( ! Тот Perl с которым работаем в командной строке 4й версии ,а на сервере стоит 5й версии.Если ваша CGI-программа использует при этом какие-нибудь преимущества 5-й версии (например обьектно-ориентированые модули),то вы думаете отладить ее низ -ошибаетесь!.Только приготовтесь к тому, что я сейчас скажу,вы сядте,а то упадете ;)) :
Закоментируйте всю вашу программу ,т.е. перед каждой строчкой поставьте символ ‘#’. После чего,добавьте вот такие строчки: ,Должно получится так: А теперь запускайте скрипт.Естественно он выдаст Одно только слово ‘Test’. Разкоментируйте несколько строчек.Еще раз запустите скрипт.Он опять выдаст ‘Test’. Значит синтаксически эти только что разкоментированые строчки были правильные. И так далее.
Если очередной раз после раскоментирования вы запустили скрипт и получили ‘Internal Server Error’ — значит в этих строках содержалась какая-та синтаксическая ошибка. Это способ отловки синтаксических ошибок трудоемок,но к нему придется прибегнуть если ваш скрипт писан под ту версию Perl,что на сервере,а не под ту что у вас.
Узнать версию Perl можно
Ну вот мы отловили в нашем скрипте все синтаксические ошибки,он заработал, но это не значит,что он работает правильно.
Что еще можно посоветовать при отладке CGI-скриптов от ошибок возникающих во время выполнения программы. Допустим какой-то файл не открылся.Конечно показывать перепуганому пользователю эти технические подробности никчему,поэтому заведите себе специальный файл debug.txt и пусть ваши скрипты пишут в этот файл причины своих ошибок и сбоев, да и вообще о всех непредвиденых событиях.
Это можно реализовать так: Примеры использования (Напомню,что встроеная переменная Perl $! содержит сообщение о причине последней ошибки,поэтому включайте ее всегда в свои сообщения): Потом можно периодически заглядывать в этот файл debug.txt и смотреть,какие ошибки встречались при работе ваших скриптов.Таким образом ваши скрипты сами помогать будут в своей отладке ;).

Также очень может оказать помощь (может и не оказать) просмотр http‘шных логов. Все обращения к URL на сервере и все возникающие при этом ошибки идут в логи сервера httpd. Сразу хочу предупредить — размеры этих логов даже на средних размеров сервере достигает десятков мегабайт. Поэтому даже не пытайтесь их вот так просто посмотреть.- Лучше если вы уж за данное дело взялись — воспользуйтесь такими утилитами как grep,head,tail,more,less. .

Кстати я хочу сказать о причине еще одной (совсем не очевидной) ошибки.Если вы набрали скрипт у себя дома на компутере,то полученый скрипт состоит из текста в DOS‘ом формате, а не в Unix‘ом так что имейте это ввиду. Запускать вам его придется в системе Unix , так что следует перевести програмный текст в нужный формат.
Дело в том что в системах DOS и Windows (это уж очередной раз скажите все что вы думаете о Билле Гейтсе и Ко) для разделения строк используетс не один («\n»),а пара символов («\r») и («\n»). Для простых HTML-файлов это не критично — браузеры игнорируют такие символы при выводе. Но скрипт является ПРОГРАММОЙ. А в программе никаких символов возврата каретки быть не должно!! Особенно в первой строке. Потому что когда операционная система запускает скрипт, она определяет какое приложение запустить для обработки данного скрипта именно по первой строке. В первой строке как вы знаете содержится #!/usr/bin/perl или #!/usr/local/bin/perl .Поэтому при запуске скрипта mysrcipt (это кстати вы можете сами увидеть коммандами top и ps) Система запускает комманду .А теперь представьте что будет если не убрать символ возврата каретки из Windows-файла. Получиться и естественно что такого приложения нет, и следовательно попытка выполнить коммаду ни к чему не приведет.
Как с таким злом бороться я раскажу в моей следующей главе.

Trics and traps

Примеры приложений:

Кто посещает мою страничку?

Гостевая книга

Счетчик посещений

Наверное тоже одним из часто встречающихся приложений CGI являются счетчики посещений. Они стоят практически на каждой страничке, возможно даже и у вас. Но иногда вас не устраивает тот факт, что счетчик лежит где-то в другом месте.Из-за этого скажем невозможно начать счет с произвольного числа.Или еще некоторые счетчики по разному фильтруют ‘Reload’. Да и мало ли? Ну а иногда вам хочется просто сделать другой дизайн цифр. То если вы CGI-програмист то возможно имеет смысл написать свой счетчик. И делать с ним что захочется. Вот я так-же написал.
Скрипт данного счетчика обслужевает несколько счетчиков ,им вы присваиваете идентификаторы. Поэтому вы спокойно можете втыкать независимые счетчики в разные страницы сайта и даже давать это делать друзьям. В общем он прост в использовании: , Где name -любое уникальное имя идентифицирующее счетчик.Вытакже можете задать необязательный параметр dig который задает количество цифр в счетчике ,Например:

Получится примерно вот так:
.gif‘ы в счетчике с прозрачными областями.Что дает дополнительную гибкость к примеру для улучшения внешнего вида с помощью другого фона его иногда имеет смысл запихнуть в «таблицу»:

Свои данные он пишет примерно в такой файл counter.dat: Вы спросите,зачем столько информации? Чтобы отфильтровывать нажатия Reload. Если с одного IP-адреса между заходами промежуток меньше чем 30 секунд,то счетчик не инкрементируется (Так например поступает счетчик в Rambler‘е).
Теперь об исходнике. Скрипт получился великоват,потому,что сдесь большую часть занимает генерация .gif — файлов.. Выглядит громоздко , зато пашет как трактор ;))!! Если вам циферки не понравились вы их легко сможете заменить.

Вместо заключения

Оглавление:

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

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

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

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

Вот это самое главное в запросе

Ну тут дальше идет посылаемая браузером информация о себе и о том что более подробно ему надо.(Например Accept: */*)

Ну и если запрошен простой файл например .html то если если такой файл есть, То сервер отошлет браузеру ответ:

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

Итак . приступим.

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

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

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

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

cd public_html
mkdir cgi-bin
chmod 0777 cgi-bin

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

chmod +x first.cgi

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

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

perl -с first.cgi

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

Разберем скрипт:
Первая строка #!/usr/bin/perl Просто указывает где в системе расположен компилятор Perl. Обычно он находится /usr/bin/perl или /usr/local/bin/perl ,выяснить это можно одной из комманд или ну или (что очень долго) запустить полный поиск .
Вторая строка это просто коментарий -вы можете тыкать чо угодно после знака #, однако я пишу обычно во второй строке название скрипта, что очень удобно.
Затем идет print «Content-Type: text/html\n\n»; Это заголовок указывающий тип содержимого.
Все что скрипт печатает в свой стандартный вывод STDOUT идет на обработку к серверу. Пустая строка отделяет заголовок от тела,которое в нашем случае представляет собой
Сервер обработает ответ скрипта и на базе него сформирует и пошлет браузеру ответ.(Сервер обычно не изменяет тела сообщения,он только дополняет заголовок нужными для работы протокола 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-соединении и о запросе.
Вот эти переменные:

Это одно из самых главных поле используемое для определения метода запроса 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)

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

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


Давая запрос на сервер браузер обычно расчитывает получить информацию определеного формата,и для этого он в заголовке запроса указывает поле Accept:,Отсюда скрипту поступает cписок тех MIME,которые браузер готов принять в качестве ответа от сервера.
Пример:HTTP_ACCEPT=text/html,text/plain,image/gif

Браузер обычно посылает на сервер и информацию о себе,чтоб базируясь на знании особеностей и недостатков конкретных браузеров CGI-скрипт мог выдать информацию с учетом этого. Например,разные браузеры могут поддерживать или не поддерживать какие-то HTMLые тэги.
Пример:HTTP_USER_AGENT=Mozila/2.01 Gold(Win95;I)

Имя хоста к которому обращается браузер. Так как физически на одном сервере может находиться сразу много серверов (Виртуальные Хосты), то должен быть способ сообщить серверу к какому именно идет обращение. Скрипт же может тоже в зависимости от этой переменной производить различные действия, таким если он используется на сайтах сразу нескольких виртуальных хостов.
Пример:HTTP_HOST=www.nnov.city.ru

Ну,начнем применять на практике усвоеные уроки. Так как все ваши .cgi -файлы должны быть исполняемыми то чтоб облегчить себе жизнь заведите себе в директории cgi-bin командный файл mkcgi ,содержащий и сделайте его в свою очередь исполняемым chmod +x mkcgi -он сильно упростит вам жизнь.
Ну а теперь запускайте скрипт.
Изучив информацию,выдаваемую данным скриптом вы сможете лучше ориентироваться в переменных окружения CGI.

Прекрасный язык Perl

Вы наверное обратили свое внимание что CGI скрипты пишутся обычно на языке Perl (Practical Extraction and Report Language)— очень удобном языке,впитавшем из других все лучшие черты.Может у вас возникнуть сомнение :Ну вот!Изучать новый язык программирования!? Спешу вас успокоить,изучение Perl не будет в тягость (я сужу по своему опыту!). Вы даже сами не заметите как выучите его.Если вы хоть когда-нибудь программировали скажем на C и использовали утилиту grep для поиска регулярных выражений в тексте,то вам будет еще легче. Для Perl родной платформой является Unix поэтому пользователям PC он мало известен. Мое целенаправленое доведение Perl до широкой публики началось с того что я скачал Perl под Windows (фирмы ActiveWare) К нему прилагается отличная гипертекстовая HTML— документация, даже быстрого просмотра которой хватит , чтобы начать хорошо и широко использовать его. Хоть он значительно уступает и по скорости и по эффективности своему Unix’ному аналогу, все равно самый лучший способ изучить язык это программировать на нем. Если вы как я дома используете большую часть времени не Windows а Unix то с изучением Perl у вас вообще не должно быть особых сложностей. Я же от себя могу сказать, что даже после небольшого опыта изучения его, он стал моим любимым языком программирования.

Все в нем сделано для удобства программиста (в отличии например от Java ;( )
Начнем с переменных,они в Perl бывают 3х типов скаларные,списковые(массивы) и хэши(ассоциативные массивы). Для указания компилятору(да и для немалого удобства программиста) перед именем скалярной переменной стоит знак ‘$’ перед массивом ‘@’,перед хешем ‘%’. т.е. например $scalar_var,@array_var,%hash_var Скалярные переменные могут быть как числовые так и строковые,но это не надо указывать Perl сам по контексту в зависимости от операций может привести одно к другому.
Например: «123»+»4″ будет 127 (или «127») так как операция ‘+’ действует над числами а вот если применить операцию конкатенации строк ‘.’ то строковое «test» . 1 будет «test1»
Ну а вот операции над скалярными переменными:

Операцыи Описание Пример
+ — * / % Арифметические print 2*7+4/(8%3);
print int(127/15); #целая часть
** Возведение в степень print 2**16;
++ — Инкремент-декремент $i++;
& | ^

>

Побитовые $x=3;$y=4;
print $x|$y;
print $x&$y;
== != = Числовые операции сравнения if($x==9)
eq ne lt gt le ge cmp стрковые операции сравнения if($game eq ‘doom’)
|| && ! Логические if(($x==9)||($game eq ‘doom’))
?: Условный оператор $x=($game eq ‘quake’?9:8);
, Последовательное вычисление $x=10,$y=20;
. Конкатенация $x=’http://’.’www.uic.nnov.ru’;
x Повторение $x=’1234’x5; #$x=’12341234123412341234′
=

Сопоставление с образцом if($url= То же но с отрицанием if($url!

= >= .= x=

Присваивание $x+=$y;

Пусь это будет вам справочником ,да кстати насчет строк,вы заметили,что они могут быть в двойных и одинарных кавычках, разница между ними состоит в том ,что в одинарных не осуществляется подстановка переменных, а в двойных осущестляется, Например: Списки: Спискочные переменные начинаются с символа ‘@’ конструируются следующим образом Также можно список использовать как lvalue: Можно обращаться к нескольким,выбраным элементам массива(срезу массива): Обратится к скаларному значению -элементу массива можно $имя_массива[индекс], сдесь обратите внимание на знак ‘$’— мы ведь обращаемся к скаляру-элементу.
Теперь немного о хешах:
хеш это такой массив который состоит из пар ключ-значение, весь хеш обозначается %хеш ,к отдельным элементам доступ $хеш конструируется хеш так: Хеш может быть также сконструирован из массива с четным числом элементов где пары превращаются в ключ-значение удаление из хеша -операция delete: есть функции выдающие ключи и значения соответственно. Операторы:
Набор операторов в Perl Очень широк,многие из них прямые аналоги имеющихся в других языках,например if,for,while;но есть и значительные улучшения имеюшихся и конечно новые.
Тот же самый оператор if имеет две формы (как когда удобнее): В пару к оператору if имеется оператор unless : означающий if с отрицанием: Также в пару while существует until
синтаксис оператора for полностью аналогичен C: новшеством(и приятным) является foreach позволяющий пройтись по всем элементам массива,присваивая по очереди его элементы какой-то переменной, его синтаксис такой:
Последний пример особенно важен для упрощения вашего тяжкого труда програмиста и демонтстрирует интересную особенность Perl-переменную по умолчанию $_: в оргомном количестве операторов и функций при опускании аргумента она подразумевается по умолчанию. Она также по умолчанию сопоставляется с регулярным выражением: как видите затраты труда значительно сокращаются,благодаря этому маленькому трюку.

Регулярные выражения.
регулярное выражение записывается между двух слэшей /рег_выр/ это самый простой пример применения регулярного выражения а теперь посложнее вот тут в табличке (из того что я помню наизусть):

Символ Значение Пример применения
. Соответствует любому символу print if /ab.c/;
[мн-во симв] Соответствует любому символу из данного мн-ва /[abc]d/;#соответствует ad,bd,cd
[^мн-во] Отрицание мн-ва символов /[^xyz]/;#
(. ) Группировка элементов(и также запоминание в переменных $1 $2 $3 . ) /(xyz)*/
/([abc].[^xy]qwerty)/
(..|..|..) Одна из альтернатив
* повторение образца 0 или более раз /.*/;#соответствует всему
? Повторение 0 или 1 раз /(http:\/\/)?.*\.cgi/
+ Повторение 1 или более раз
повторение от n до m раз
повторение точно n раз
повторение n и более раз
Спец символы:
\t \r \n . Управляющие символы:табуляции,возврат каретки,перевод строки.
\d Соответствует цифре,Аналог [0-9]
\D Соответствует нецифровому симсволу,аналог[^0-9]
\w Соответствует букве
\W Соответствует небуквеному символу
\s Соответствует пробельным символам(пробелы,табуляции,новые строки..)
\S Соответствует непробельному символу
\b Соответствует границе слова $test1=»this is test»;
$test2=»wise»;
if($test1=

/\bis\b/)#нет

\B Соответствует не границе слова /\Bis\B/ соответсвует ‘wise’ но не ‘is’

Для того чтоб поместить в регулярное выражение любой специальный символ,поставьте реред ним обратный слэш Заставить Perl игнорировать регистр можно поставив i после регулярного выражени
Полезные функции.
В Perl очень много различных функций ,как говорится на все случаи жизни,все о них конечно не опишу,но обо многих. Начну с тех,которые больше относятся к операторам. Операция замены s/рег.выражение/строка/ игнорировать регистр — опция i глобальная(по всей строке) замена -опция g; Пример: Очень полезная опция у s/// e -она означает что вторая строка не строка а выражение, результат которого и будет подставлен. Например,у вас есть файл в котором все записи о возрасте через год надо менять или более показательным примером послужит функция urldecode,которая будет встречатс в каждой вашей программе,обрабатывающей формы: Также важным удобством в Perl являются операции для работы с файлами для выполнения схожих функций в других языках приходиться проделывать огромную массу работы. Аргументами могут быть как Файловые переменные,так и строки,представляющие имя файла.

Операция Описание Пример использоввания
-r Доступен для чтения unless(-r «myfile»)
-w Доступен для записи
-x Для исполнения
-o Принадлежит пользователю if(-o «index.htm»)
-R Доступен для чтения реальным
пользователем,а не только «эффективным».
Имеет значения для set-uid -скриптов
if(-r FILE)>
-W Доступен для записи реальным пользователем
-X Доступен для исполнения реальным пользователем
-O Принадлежит реальному пользователю
-e Файл или каталог Существует unless(-e $htmlfile)<
open(HTML,»>$htmlfile»);
print HTMLFILE » «;
close(HTMLFILE);
>
-z Существует,но имеет нулевую длину if(-z ‘tmpfile’)
-s Размер файла в байтах system(«rar m -m5 archive.rar $myfile») if -s $myfile > 1000;
-f Файл существует и является простым файлом
-d Файл существует и является каталогом if(-d ‘public_html’)
-l Символической ссылкой
-p Каналом FIFO
-u Имеет бит установки пользователя
-g Имеет бит установки группы
-k Установлен sticky-бит
-t Является терминальным устройством
-M Время с последнего изменения (в днях) while(defiled($file=glob(‘*’))) <
if(-M $file >= 7.0) <
unlink($file);#удаляем слишком старые файлы
>
>
-A Время последнего доступа(в днях) if(-A «$ENV<'HOME'>/public_html/index.html»
избавиться от символа новой строки на конце поможет функция chomp, ведь этот символ может помешаться например в имени файла или при выводе на экран Если также подставить списочную переменную,то получим список строк файла от текущей строки и до конца бинарный файл можно читать и писать функциями sysread и syswrite:
sysread(ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт)
syswrite(ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт)
функции split и join: @Список=split(/рег.выр/,$скаляр);
$скаляр=join(строка,@Список);
Встроеные функции Perl можно вызывать со скобками или без (как вам удобно), скобки программисты указывают или для красоты,или чаще,что устранить возможную неоднозначность в выраженнии: Надеюсь что я вас позабавил примерами функций ;).

Примеры применения Perl для различных нужд.
Следующая программа переводит текстовый файл в формат HTML (вспомните сколько хлопот вам доставит отлов во всем файле ‘ ‘ и ‘&’ чтоб заменить их на &tl; , > и & а как неплохо чтоб автоматически все http://www. превратились в http://www. ) Более подробную информацию о Perl вы можете получить по адресам:
http://www.perl.com
http://www.metronet.com/0/perlinfo/perl5/manual/perl.html
http://www.ActiveWare.com/

Заголовки запросов и ответов

Даже если вы и знаете кое-что о HTTP все равно не лишне будет вспомнить о том как это все работает тем более на эту информацию придется ориентироваться при написании CGI скриптов.
Этапы соедирения.
Первый этап это когда HTTP -клиент(браузер) соединяется с сервером.для этого он использует протокол TCP/IP соединение происходит к известному клиенту TCP-порту (80 -номер порта HTTP) (другие сервисы сидят на других портах ,например FTP и SMTP на 21 и 25)
Вторым этапом идет запрос клиента:клиент передает заголовок запроса и возможно(в зависимости от метода) тело сообщения запроса.В заголовке обязательно указывается метод ,URI,и версия HTTP,и может быть еще несколько необязательных полей
Третий этап -ответ сервера,который опять таки состоит из заголовка,в котором сервер указывает версию HTTP и код статуса, который может говорить о успешном или неуспешном результате и его причинах.Далее идет тело ответа.
Четвертым этапом происходит разрыв TCP/IP соединения.
HTTP -запрос.
Запрос состоит из Строки запроса(она обязательна) и остальных полей. Синтаксис строки :МЕТОД URI HTTP/версия
где -пробел , -переход на новую строку
Методы HTTP.
GET
Самый часто применяемый метод,в протоколе HTTP/0.9 был единственным методом,и применяется для извлечения информации по заданому URI Может быть условным если в заголовке указано поле If-Modified-Since:

HEAD
Почти идентичен GET но отличается тем что сервер не возвращает тело обьекта а только его заголовок (метаинформацию) программы могут применять его для проверки гиперссылок на правильность,доступность и изменения.

POST
передает данные для обработки их программой ,указаной в URI сдесь обязательно указывается поле Content-Length:

Сушествуют и другие ,реже применяемые методы,например PUT -для сохранения передавемых данных в указаном URI и DELETE для удаления ресурса.

Поля заголовка запроса.
После строки запроса идут поля заголовка запроса. Поля общего(general-header) заголовка (он общий как для запросов так и для ответов):
Date:
Указывает дату запроса,например:
Date: Sun, 20 Nov 1994 08:12:31 GMT

MIME-version:
Указывает версию MIME (по умолчанию 1.0)
MIME-version: 1.0

Pragma:
Содержит указания для таких промежуточных агентов как прокси и шлюзы,
Pragma: no-cache

Поля относящиеся к запросу(Request-Header):
Authorization:
Содержит информацию аутентификации
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

From:
Браузер может посылать адрес пользователя серверу
From: quake@doom.ru

If-Modified-Since:
используется при методе GET ресурс возвращается ,если он был изменен с указаного момента, может использоваться при кешировании.
If-Modified-Since:Mon 15 Jul 1997 00:15:24 GMT

Referer:
Содержит URL предшествующего ресурса.
Referer: http://www.uic.nnov.ru/

User-Agent:
Програмное обеспечение клиента.
User-Agent: Mozilla/3.0

Заголовок информации сообщения (Entity-Header) применяется как в запросах так и в ответах (при этом некоторые поля только в ответах):
Allow: (в ответе сервера)
Список методов,поддерживаемых ресурсом.
Allow: GET, HEAD

Content-Encoding:
идентифицирует метод кодировки,которым был закодирован ресурс
Content-Encoding: x-gzip

Content-Length:
Длина тела сообщения
Content-Length: 102

Content-Type:
Содержит тип ресурса(MIME),для текстовых еще и кодировку символов(необязательно)
Content-Type: text/html; charset=windows-1251

Expires: (в ответе сервера)
Дата окончания действия ресурса,применяется в кешировании для запрета кеширования устаревших ресурсов (в ответе)
Expires: Tue, 24 Sep 1998 23:00:15 GMT

Last-Modified: (в ответе сервера)
Время последнего обновления ресурса
Last-Modified: Tue, 23 sep 1998 13:48:40 GMT

Другие поля:
Поля Accept: указывают серверу выдавать только указаные форматы данных,которые клиент может распознать.
Accept: text/html
Accept: text/plain
Accept: image/gif

Поле Host: служит для того , чтобы указать, к какому хосту идет обращение. Данное поле не входит в число обязательных. Однако оно является необходимым в тех случаях, когда одному физическому серверу соответствует несколько виртуальных хостов. В этом поле тогда указывается какой из виртуальных хостов имеется в виду.
Host: www.nnov.city.ru

Примеры запросов: Ответ HTTP-сервера.
Ответ идет от сервера.Состоит он из строки состояния и затем поля ответа Общий заголовок(General-Header) и заголовок тела сообщения (Entity-Header),которые уже описаны при обсуждении запроса. и еще идет заголовок ответа(Response-Header).
Строка состояния имеет следующий формат:
HTTP/version Status-Code Status-Phrase
где HTTP/version версия,Status-Code -3х значный код,и Status-Phrase текстовая фраза, поясняющая код ,пример: HTTP/1.0 200 Ok
,200 -код означающий успешную обработку запроса,что и поясняет «Ok» Заголовок ответа состоит из полей:
Location:
Содержит URI ресурса,может быть использован для переключения клиента в другое место, если например ресурс был перемещен в другое место или на другой сервер.
Location: http://www.uic.nnov.ru/newlocation/index.html

Server:
Информация о програмном обеспечении сервера
Server: Apache/1.1

WWW-Autenticate:
Параметры аутентификации.
WWW-Autenticate: Basic realm=»doomsday»

Коды ответов HTTP.

Код статуса Значение
200 OK
201 Успешная команда POST
202 Запрос принят
203 Запрос GET или HEAD выполнен
204 Запрос выполнен но нет содержимого
300 Ресурс обнаружен в нескольких местах
301 Ресурс удален навсегда
302 Ресурс отсутствует временно
304 Ресурс был изменен
400 Плохой запрос от клиента
401 Неавторизованый запрос
402 Необходима оплата за ресурс
403 Доступ Запрещен
404 Ресурс не найден
405 Метод не применим для данного ресурса
406 Недопустимый тип ресурса
410 Ресурс Недоступен
500 Внутренняя ошибка сервера
(это по вашу душу,юные CGI-программисты ;( )
501 Метод не выполнен
502 Неисправный шлюз либо перегруз сервера
503 Сервер недоступен/тайм-аут шлюза
504 Вторичный шлюз/тай-аут сервера

Более подробное описание всех кодов можно найти в RFC-1945
Несколько примеров:
CGI-заголовок.
В том случае когда запрашиваемый URI есть CGI-скрипт сервер базируясь на данных запроса создает среду переменных CGI и передает управление скрипту скрипт должен выдать CGI-заголовок,после которого и идет тело ответа,сгенерированое скриптом.
Заголовок (CGI-Header) состоит из полей:
Content-Type:
Должно обязательно присутствовать,если есть тело.
Content-Type: text/html

Location:
Содержит URL ресурса на который скрипт перенаправляет запрос.Как правило,если присутствует это поле больше ничего не указывается.
Location: http://www.idsoftware.com/index.html

Status:
Позволяет CGI скрипту вернуть статус обработки,если это поле не задано,то сервер подразумевает
Status: 404 Not found

На базе этой информации сервер и формирует окончательный заголовок,который и передается клиенту.
Примеры: nph-скрипты.
Иногда возникает необходимость чтобы CGI -скрипт сам отвечал напрямую клиенту, минуя разбор заголовка.Это во-первых уменьшает нагрузку на сервер,и во вторых, что самое главное такой прямой ответ клиенту позволяет скрипту полностью контролировать транзакцию.Для этого существуют nph-скрипты(Not Parse Header) ,имя скрипта должно начинатьс с префикса «nph-« ,Например «nph-animate.cgi» .Такие скрипты сами формируют HTTP-ответ клиенту,что полезно при анимации:
Этот пример вам выдаст анимацию ,составленую из нескольких .gif -файлов.Если же вы получили вместо анимации сообщение об ошибках,то вам следует,может быть перейти к следующей главе, которая поведает вам о правах доступа- того,без чего Unix не был бы Unixом.

Права Доступа

Я бы ни за что не написал этот раздел,если бы он не был так важен.Сидя в пределах своей домашней директории и занимаясь только тем,что качаете с Инета всякую херню,вы возможно и не задавались некоторыми вопросами. а зря. Ведь немного надо,чтоб попортить нервы начинающему CGI -програмисту.
Одна из таких вещей это права доступа.
Начнем с того ,что в системе Unix каждый пользователь имеет свой идентификатор- число,уникально идентифицирующее его в этой системе.(Мой логин paaa а ему соответсвует число 1818).Это число внутреннее для операционной системы,для пользования оно представлено как логин,который и соответствует пользователю.
Только не надо думать о пользователе,как о конкретном человеке сидящим за клавиатурой, пользователем может быть и какой-нибудь процесс.Важно отметить что пользователь-это определенна область прав доступа,которая ему соответствует.(Вы например не можете обычно писать и удалять файлы из каталога другого пользователя). Это и дает возможность стабильной работы всей системы.
Итак есть идентификатор пользователя.Также имеется идентификатор группы.
Группа служит для выделения пользователей по группам. Например у пользователей группы users (Обычные пользователи) не такие права как у группы wheels (административная группа).
Каждый процесс который вами запущен(Будь то Netscape,терминал,или текстовый редактор)получают ваши идентификаторы пользователя и группы. таким образом исполняются от вашего имени.
Теперь рассмотрим повнимательней файловую систему.В Unix с файлом связано много характеристик. Во-первых в системе нет «ничьих» файлов ,все файлы имеют владельца-пользователя и владельца-группу. Любой файл который вы создаете автоматически получает ваш идентификатор.По этому система очень легко отслеживает, чьи это файлы и каталоги.
Следующее новшество по сравнению с DOS это права доступа к файлу.Их может сменить только тот пользователь которому принадлежит файл,или супервизор.(Это в отличии от DOS где каждая дрянь типа вируса может снять атрибут readonly читать и писать все файлы ;()
Права доступа задаются обычно числом в восьмеричной записи и разбиты на 3 части по 3 бита: Каждая часть задает права доступа для конкретной группы:

1я -права доступа для пользователя,которому принадлежит файл
2я -для группы которой принадлежит файл
3я -для всех остальных

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

Бит Описание
8 Право на чтение для пользователя
7 Право на запись для пользователя
6 Право на исполнение для пользователя
5 Право на чтение для группы
4 Право на запись для группы
3 Право на исполнение для группы
2 Право на чтение для всех остальных
1 Право на запись для всех остальных
Право на исполнение для всех остальных

Изменяются права командой chmod,ее синтаксис такой:
chmod [u|g|o]<+|-> file
chmod number file
,где uuser,ggroup,oother,rread,wwrite,x-execute;-удалить,+-установить
Примеры:
chmod +r file.txt #разрешает всем право на чтения файла
chmod u+w file.txt #устанавливает для владельца файла право на запись в него
chmod +x gbook.cgi #право на исполнение для всех,как для ползователя,группы,и для других
chmod 0777 cgi-bin #Разрешает самые широкие права доступа для cgi-bin

Приоткрытии файла программой,операционная система сравнивает идентификатор пользователя с идентификатором пользователя владельца файла, если они равны,то действуют права пользователя,если не равны то сравниваются идентификаторы группы,если и они не равны,то действуют права доступа для остальных остальных.В том случае если у процесса нет достаточных прав,система возвращает ошибку. Следует заметить ,что для супервизора root права доступа не проверяются.
Можно выполнить скрипт,только если есть права на его исполнение. Вот почему следует давать chmod +x *.cgi иначе ваши скрипты станут просто недоступными. Но и это еще не все.
Ваш скрипт может обращатся к вашим файлам (например ведет базу данных гостевой книги). Все выглядит нормально,но только ничего не работает,файл в который вы намеревались писать,
не открывается,знакомая проблема ;(( ?.Так вот чтобы вы не мучались в догадках Ваш скрипт не может получить доступ к вашим файлам,потому что он выполняется не вами (не с вашим идентификатором), а от имени nobody (непривелигированый пользователь).Это мера предосторожности направлена на то, чтоб скрипты ,взбесившись из-за неправильно переданых параметров(или вообще от глюков) не могли ничего повредить ценного и важного на сервере.
Поэтому к тем файлам,к которым скрипт по смыслу должен обращатся нужно присвоить самые широкие права доступа 0777
Например в случае гостевой книги chmod 0777 guestbook.dat
Если также важно чтоб скрипты могли заводить новые файлы в cgi-bin то надо дать также права на это chmod 0777 cgi-bin
Если вы видите что ваш скрипт не может обратится к какому-то файлу,то это в 99% случаев из-за вашей забывчивости.
На самый крайний случай воспользуйтесь setuid-скриптами (к этому делу ,если вы на это решились,отнеситесь ОЧЕНЬ серьезно,так как целые тома по безопасности в Unix посвящены именно setuid-программам). Хочу сразу предупредить ,сам я таких не так уж много писал,да и вам не особенно советую. Но для общего как говорится развития,имейте в виду следующую информацыю.
Кроме указания прав доступа,существуют специальные биты у файла.Это биты установки пользователя и группы. Когда процесс выполняется(простой процесс) то его реальный и эффективный идентификаторы пользователей совпадают,идентификаторы групп тоже. На самом деле значение имеют как раз эффективные значения пользователя и группы,они учавствуют в сравнении прав доступа. Нельзя ли их как-то изменить,когда уж совсем нужда заставит? Можно! .На этот вопрос дают ответ программы с установленым битом пользователя.Когда система запускает такую программу,она присваивает новому процессу не идентификатор того пользователя,что запустил ее, а идентификатор пользователя-владельца исполняемого файла.
Самый классический пример setuid-программ это программа passwd ,предназначеная для смены пароля пользователя. Такие данные как пароль и прочие характеристики пользователей хранятся в специальном файле,который имеет огромное значение при входе в систему. Так как это системный файл,то открыть к нему доступ на запись всем-значит подвергнуть ВСЮ систему риску,ведь любое неправильное изменение его повлечет катастрофические последствия(в конце концов бывает просто хулиганство). Поэтому доступ к этому файлу закрыт для всех пользователей.А что если надо сменить пароль? Запускаем программу passwd! Если глянуть на ее аттрибуты ,то видно что она принадлежит root -супервизору, и еще имеет установленый бит setuid. Так корректно обходится эта проблема.
Если вы все-же решили попытаться ,то знайте ,что сделать программу setuid можно
коммандой : chmod +s myprogramm

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

Генерация ответа

Большую часть того что нужно знать о генерации ответа,я сказал в разделе Заголовки запросов и ответов.Нет,не угадали! Я не буду сдесь говорить о всяком дизайне того что вы выдаете.Этому вы успели напрактиковатся на HTML -страничках.
Я поговорю о MIME (Multipurpose Internet Mail Extension).И о разных браузерах.
Стандарт MIME появился в электронной почте (e-mail) потому что остро стала проблемма пересылки по e-mail различных данных в различных форматах.Так как HTTP тоже работает с различными типами данных то поэтому тоже использует MIME для своих нужд. Типы MIME состоят из Типа и подтипа (например text/plain,где text-указывает на наличие текстового содержимого,а plain-уточняет его как простой текст) приведеный ниже список (он далеко не полн,типов MIME огромное количество) описывает некоторые часто встречающиеся типы.: text/html text/plain text/richtext image/gif image/jpeg image/tiff audio/basic audio/32kadpcm audio/ video/mpeg video/quicktime multipart/mixed multipart/alternate multipart/ application/octet-stream application/msword application/postscript message/digest
Информация о MIME больше возможно пригодится вам в том случае если вы собираетесь работать из ваших скриптов с электронной почтой,но и для WWW она не повредит. Особенно знание Content-Type:
Content-Type:
Состоит из типа и подтипа типы могут быть как стандартные так и экспериментальные начинающиеся с префикса ‘x-‘:

text
Текстовые данные.Первым подтипом который включен сюда это plain,что значит простой текст. сюда же включен самый ходовой формат html .У типа text как и у многих типов могут быть параметры,главным из них является charset он как раз и указывает на раскладку символов, которая применена в тексте, так что если вы хотите указать браузеру какую раскладку применять, то просто укажите charset:
Content-Type: text/plain; charset=us-ascii
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=koi8-r

multipart
Данные которые могут состоять из нескольких частей,различных типов данных.Поэтому параметром multipart служит boundary, позволяюший указать разделитель.Каждый фрагмент в многочастевом сообщении имеет свой Content-Type: (Он может быть также multipart,т.е. допускаются вложеные multipart,главное чтоб boundary были разными).В электронной почте применяется больше multipart/mixed (основной подтип) и multipart/alternative (Он отличается тем что показывается одна из альтернатив,например сообщение шлется в простом и HTMLом форматах,и почтовая программа показывает либо часть,которую она способна отобразить). В WWW -програмировании распостранен x-mixed-replace ,который означает что следующая часть должна заменить предыдущую после подгрузки, что применяется для анимации(см.Пример с анимацией).
Теперь о разделителе,его надо выбирать так,чтоб он не встретился где-то в данных (т.е. что-то вроде «diUr344rnmvforgefvrg923rghyj2»).Когда вы задали разделитель,например boundary=»boundary» то когда закончилась одна часть,вы должны выдать строку —boundary,последн часть —boundary—,причем эти разделители должны быть на отдельной строке,а не сливаться с текстом:
Пример:

message
Представляет инкапсулированое почтовое сообщение.Используется в e-mail ,а не в WWW.

image
Некоторое Графическое изображение.(чаще всего image/gif и image/jpeg)

application
бинарные данные какого-нибудь приложения.В том случае если данное приложение может быть запущено,Браузер запускает его.Например при поступлении данных application/msword Браузер спросит,нужно ли запустить Word для просмотра досумента.При отсутствии нужного приложения браузер спросит в каком файле сохранить данные.Подтип octet-stream как раз и означает поток байт информации,который и используется по умолчанию.(К сожалению не все так гладко,известен глюк в Netscape Navigator‘е который вместо того чтоб сохранить application/octet-stream пытается его показать как text/plain что если это сгенерировано из CGI,ни к чему хорошему не приводит ;(()
Что касается application ,то Вы можете тут смело извращатся,используя x- типы данных,
Например application/x-fuck-to-netscape-navigator. ;)))))
Часто используемый параметр name позволяет указать имя файла.Например:
Content-Type: application/msword; name=»readme.doc»
Что полезно при полученнии файлов через HTTP,причем этот параметр может применятся и для других типов таких image или audio ,Например:
Content-Type: image/gif; name=»myfoto.gif»

Content-Transfer-Encoding:
Применяется больше в системе электронной почты и обозначает метод кодирования, которым были закодированы данные при передаче сообщения.Например:
7bit 8bit quoted-printable base64 binary x-типы
MIME-Version:
Указывает версию MIME .

Теперь поговорим о разных браузерах вы знаете что браузеры бывают разные,разных версий на разных платформах, поддерживают и не разные тэги и глюки у них тоже разные. ;((( .
Это могло попортить много нервов WEB-дизайнерам и конечно же нам ,CGI-програмистам. Профессионально написаный сайт от просто хорошего отличается тем что хорошо выглядит Не только на экране того браузера,которым пользуется сам его автор,а на других тоже.
Если вы используете JavaScript для своих страничек,то вы уже наверно использовали (или хотя бы вам в голову приходила мысль использовать)свойства navigator.AppName navigator.AppCodeName navigator.appVersion navigator.userAgent:
Ну не волнуйтесь вы так ,мы CGI-программисты не в самых худших условиях на этот счет. Вспомните о том что браузер сам при запросе посылает вам данные о себе и о своей версии. И делает он это для того,чтобы эту информацию можно было учесть.
В запросе он указывает User-Agent: которое и попадает на сервере в переменную среды HTTP_USER_AGENT ,которую и можно использовать.
Например если в ней содержится Mozilla/3.01Gold (Win95;I) то значит вы имеете дело с Netscape (Mozilla-кодовое название Netscape Navigator‘а),версии 3.01Gold и далее после имени и версии может следовать необязательная информация ,например как в приведеном примере о платформе Win95 и о том является ли версия U -для США (USA) или I -международной(International). Напомню,что такая информация необязательна.(То есть если браузер послал информацию User-Agent: то гарантировано расчитывать вы можете только на Название/Версия).
Ну вот я слишком много развел демагогии,пора переходить к практическим примерам.
Допустим ваш скрипт генерирует какие-то тэги,которые слишком старые браузеры не поддерживают,причем без них не обойдешся,они составляют всю ‘изюминку’ сайта.
Ну уже почувствовали,насколько это здорово.А вот еще примерчик.Это из разряда того, что тэги бывают разные.Например в Explorer есть тэг BGSOUND предназначеный для проигрывани музыки на страничке.(В Netscape этого тега нет,и поэтому для втыкания музыки приходится использовать подключаемые модули plugin).Мутится с этими Плугинами Вам в облом,а хочется побаловать человека хорошей музыкой,если браузер позволяет. Ну вот вы уже можете управлять этим процессом.Только не забывайте,что если вы не получили информацию о клиенте(так может быть,если например ваш скрипт вызвал какая-нибудь поисковая машина) то не в этом случае не надо делать никаких предположений,а просто пусть ваш скрипт продолжает делать то что должен был делать.

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

Обработка Форм

Ну вот ,вы уже знаете достаточно,кое в чем уже успели приобрести опыт, пришло время перейти к очень важной теме — обработке форм. При всей простоте (кажушейся) это едва ли не самое главное предназначение всего стандарта CGI . Куда бы вы не зашли на любой уважающий себя сайт,везде вы встретите формы, которые вам предложат заполнить.В этом деле можно положится только на CGI, так как Java и JavaScript ,выполняющиеся на страничке у клиента не имеют доступа к серверу,на котором находится сайт.
Коротко вспомним о том что происходит при рассматриваемом процессе поближе,так сказать на трезвую голову ;). Итак браузер требует у сервера определенный URL (это может быть как простой документ,так и сгенерированый CGI) в этом документе может содержаться форма.Отображая такой документ браузер также выводит элементы формы (кнопки, поля ввода, поля ввода пароля, переключатели, радио-кнопки, списки, текстовые области,скрытые поля). И со всем этим добром пользователь может взаимодействовать.К форме естественно имеет доступ и встроеный язык программирования JavaScript -он может как использовать форму для своих нужд,не передавая CGI,так и помогать пользователю в заполнении формы.
После того,как пользователь заполнил форму он нажимат кнопку Submit которая говорит, что форму надо отправить на сервер. Браузер собирает все имена и значения элементов формы ,кодирует их методом urlencode и в зависимости от указаного в тэге FORM метода вызывает GET или POST с указаным URL,передавая ему данные. На сервере CGI-скрипту это попадает (в зависимости от метода) либо в переменную QUERY_STRING либо на STDIN.Скрипт может проверить данные ,занести их в какую нибудь базу данных,может как yahoo выполнить какой-нибудь поиск, может что-нибудь вычислить. да мало ли что он может,все зависит только от нашей фантазии. В конце концов скрипт выдает браузеру ответ,который он и отображает.В этом ответе может содержаться все что вашей душе угодно от сообщения об удачном или неправильном запросе до таких ответов,по сравнению с которыми yahoo и altavista подвиснут от зависти, главное чтоб вам и тем кто посещает ваш сайт это нравилось.;)

Ну а теперь немного о синтаксисе элементов форм ,их описании и самое главное особенностях при обработке CGI-скриптом.
Итак немного экскурс в HTML:
FORM
Атрибуты:
action
как раз и задает тот URL,который будет и обрабатывать форму, если он опущен,то текущий URL документа(а он-то может быть сгенерирован нашим скриптом).
method
задает метод GET или POST
enctype
обычно не задается,для форм он application/x-www-form-urlencoded -по умолчанию, и поддерживается всеми CGI скриптами.Но если вы уж очень хотите чтобы браузер послал вам данные в другом формате (например text/plain) то можете указать этот тип кодировки,только потом не жалуйтесь,что ваш скрипт не может разделить поля,или вообще начинает глючить когда пользователь ввел какой-то спецсимвол.
name
Задается для JavaScript,чтоб обращатся к форме по имени,а не по номеру. Для CGI не играет ни какой роли,так как внутреннее для браузера.
target
Может Определять в какой фрейм отправить полученую информацию.Имеет значение во фреймосодержащих документах.Прозрачен для CGI обработки данных.
onSubmit
Определяет JavaScript -обработчик активизации формы.Применяется для проверки JavaScript‘ом правильности заполнения.Опять таки прозрачен для CGI.
Пример типичной формы: Форма может содержать элементы.Элементы имеют имена,которые используются дл кодирования пар имя=значение.Некоторые Элементы не передаются CGI,а используются JavaScript для управления,например кнопки.Некоторые поля передаются только в тех случаях, когда в них что-то выбрано,например списки и переключатели.Остальные поля передаются всегда, даже когда они пустые.
Например: Допустим вы ввели имя lesha и адрес paaa@uic.nnov.ru,при этом выбрали переключатель После нажатия кнопки будет отправлен вот такой запрос:
http://www.doom/cgi-bin/test.cgi?Name=lesha&Email=paaa@uic.nnov.ru&doomer=Yes
Если же вы не выбрали переключатель,то запрос будет таким:
http://www.doom/cgi-bin/test.cgi?Name=lesha&Email=paaa@uic.nnov.ru
,как видите элемент doomer не вошел в строку запроса
Теперь попробуйте оставить поля редактирования пустыми:
http://www.doom/cgi-bin/test.cgi?Name=&Email=
Эти элементы (Name и Email) присутствуют и сообщают что они пустые.

Кнопка(button)

В форме изображается кнопка,при нажатии которой вызывается JavaScript-обработчик заданый атрибутом onClick ,атрибут name служит для JavaScript-именования кнопки а не дл передачи CGI.Так как значение кнопки не передается CGI, value задает Текст,изображаемый на кнопке.

Submit

Кнопка,предназначеная для передачи формы.Опять же,сама не передается,а служит только для управления. текст на ней задается атрибутом value.
Reset

Кнопка очистки формы.При ее нажатиивсем измененым элементам возвращается значение по умолчанию.
Поле ввода(text)

Применяется очень часто,поэтому тип «text» служит для INPUT по умолчанию,его не надо каждый раз указывать.Имя поля,задаваемое name является обязательным для CGI (в отличии от JavaScript,где элементы формы можно индексировать по номерам,а имена для удобства и читабельности кода служат).Можно задать значение по умолчанию атрибутом value,которое будет после загрузки докумета.атрибут size позволяет задать размер поля.Также может содержать обработчики onBlur,onChange,onFocus,onSelect.
Текстовая Область(textarea)
Область многострочного редактирования.Размеры в строках и столбцах задаютс атрибутами rows и cols.Значения атрибута wrap «hard» и «soft» -означают соответственно мягкую или жесткую разбивку на строки (в большинстве случаев ето не существенно). На что следует действительно обратить внимание так это на символ,используемый для указания перехода на новую строку. В Windows это ‘\r\n’ а в Unix ‘\n’,так что если это для вас существенно,то приводите преобразование,например так:
$my_text =

s/\r\n/\n/g;
Поле ввода пароля(password)

Очень похоже на поле ввода,отличается тем что вместо символов в нем отображаютс символы ‘*’.Служит для ввода пользователем пароля.
Скрытое поле(hidden)

Поле не отображаемое на экране.Но оно имеет имя и значение и следовательно передается в форму. Служит для того (и очень часто програмисты его применяют) чтоб передавать скрипту какую нибудь информацию.Например,если ваш скрипт обрабатывает несколько форм разных типов,то в скрытом поле каждой формы можно указать с какой формой конкретно вы имеете дело. Так как это ваша внутренняя кухня то нечего пользователю мозолить глаза этой информацией.
Переключатель(checkbox)
Text
В отличии от кнопки,атрибут value сдесь не задает на надпись на переключателе,а его значение(внутреннее).Поэтому если надо что-то подписать,пишите рядом в ним. Может быть сразу выбраным если указан атрибут checked .Если value не указано то значение по умолчанию «on» .Передается только в том случае,когда выбран.
Радио-кнопка(radio)
Text
В отличие от checkbox может быть несколько радиокнопок с одинаковым параметром name ,но с разными value,из них передается только та,что выбрана.Одна из них может быть изначально выбрана по умолчанию checked.Например:
Список(select)
Задает список,позволяющий выбрать одну (или несколько) опций из списка. Если атрибут multiple не указан,то создается простой выпадающий список,в котором можно выбрать только одну из опций.Его значение всегда передается,т.к. всегда хоть одно выбрано. Если указан атрибут multiple,то во первых можно указать размер видимой части списка атрибутом size (Если опций больше появится скролинг).Во вторых передаются только выбраные опции ,т.е.Он может передатся несколько раз ?SelectName=opt1&SelectName=opt2&SelectName=opt9 если выбраны скажем несколько опций.А может и не разу,если ничего не выбрано из списка. Можно задавать обработчики onBlur,onChange,onFocus.
Небольшая Помощь JavaScript
Для CGI-програмиста конечно JavaScript -это иной мир,вы можете спокойно пропустить этот абзац,если вы не знаете JavaScript,так как написаное в нем к CGI не относится, а скорей к самим формам и дизайну сайта.Я скажу пару слов о том как JavaScript может оказать посильную помощь в проверке правильности заполнения форм.Все проверки конечно можно и нужно делать на сервере,но когда имеешь дело с рассеяным пользователем, то для него заполнение простой формы превратится в мучение.Поясню на примере,в форме есть какие-то обязательные поля,например имя.Если пользователь забыл его указать то скрипт скажет ему об этом в сообщении он исправит это, допустим что-нибудь еще не так ввел . Только на передачу данных по сети может уходить масса времени.А на обработку на локальной машине-доли секуды.
Вот Например как это можно применить JavaScript для предварительного контроля правильности. Допустим простейшая форма содержит имя и возраст.Имя не должно быть пустым, а возраст должен состоять из цифр. Ну вот ,на этом можно закончить это краткое введение в HTMLые формы.
Итак,У нас на входе скрипта данные формы,закодированые методом urlencode Положеные в Переменную QUERY_STRING или подаваемые на STDIN.Мы должны вопервых их получить. Вот,мы уже считали наш запрос в переменную $query.Теперь пришло самое время ее обработать. Мы знаем что поля разделены символом ‘&’ значит используем его в качестве разделителя функции split: Вот разделили,а теперь организуем цикл foreach по полученым полям @formfields Сдесь выражение в регулярном выражении в круглых скобках (.*) после знака ‘=’,запоминаетс в скалярную переменную $1 ,которая затем и декодируется нашей старой и знакомой функцией urldecode (я предупреждал,что она будет почти в каждой вашей CGI-программе) Так мы проходим по всем полям,которые нам переданы.Это стандартный подход,он годится в качестве шаблона.У вас может возникнуть вопрос,а что делать если вам переданы данные от списка у которого задана возможность выбора нескольких элементов и данные поступают в таком виде: Sel=opt1&Sel=opt2&Sel=opt9. Тут тоже нет никаких проблем,просто запихиваем эти поступающие значения в массив. И потом спокойно оперируем с Полученым Массивом @Sel.
На этом можно так сказать заканчивается шаблонная часть скрипта и начинается содержательная, которая зависит только от вашей фантазии.
Вы можете сколько угодно анализировать полученые значения,обращатся при этом к различным файлам .Если вы к этому приложите фантазию,то кто знает что получится.
А Пока Ради примера я вам напишу скрипт,который ведет социологическое исследование насчет курения и отношения к нему.Может он слишком массивен для данного пособия, но зато он наглядно показывает как достаточно простыми средствами можно проводить социологические исследования. А вот скрипт для его обработки:

Изображения ismap

Анимация

Когда говорят о каком-то популярном сайте,то частенько к преимуществам относят и анимацию. Действительно,когда изображение изменяется (и особенно к месту ;)),то это смотритс и пользователю нравится.
Говоря об анимации нужно сразу отметить что нет лучшего способа. Анимацию можно сделать ДЕСЯТКАМИ Способов,каждый хорош в своей области применения. Я перечислю только некоторые из них,которые чаще всего применяются:
Самый простой,но наименее функциональный способ это GIF с анимацией.
Потом можно воткнуть анимационный файл MPEG или AVI они более отражают суть анимации, но имеют недостаток,что для проигрывания их на некоторых браузерах нужны специальные подключаемые модули.К тому же они не интерактивны.
Можно реализовать анимацию в рамках Java-апплета,когда апплет находясь на страничке сам перерисовывается со временем.
Таким же интерактивным средством служит обращение к массиву document.images[] из JavaScript.Достоинство-помимо интерактивности,полная интегрированость с HTML -станичкой.Но может как и предыдущий использоваться только с относительно новыми браузерами,которые поддерживают Java и JavaScript.


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

Несколько советов по отладке

CGI-программы -не самые простые в отладке,по сложности отладки они способны сравнится лишь с отладкой драйверов. Вся сложность заключается в том,что скрипт выполняется не как обычная программа. Он выполняется в специальной среде сервера,которая создается при клиентском запросе, к тому же он исполняется не из под вашего аккаунта,а на непривилегированом уровне.
Если скрипт не исполняется потому,что вы допустили синтаксические ошибки,то самих этих ошибок вы не увидите,на экране будет только из-за чего она произошла вы можете только гадать. Также если вы забыли задать к какому-то файлу нужные права доступа ,то тоже будет трудно выяснить что же произошло и в чем причина ошибки (если конечно к этому вы не готовы).
Ну вот ,хватит вас пугать,тем более что нас не запугаешь ;) !
Приступим к отладке.Я вам опишу достаточно примитивные меры,которыми я сам пользуюсь.
Начнем с того что у нас есть скрипт test.cgi мы уже сделали его исполняемым chmod +x test.cgi Простейший способ проверить его на ошибки это команда Ключ -c говорит Perl что надо только проверить синтаксис.Все сообщения об ошибках вы можете видеть и подправить.Более тяжелый случай состоит в том когда Perl встроен в Web -Сервер, причем версии разные.Как у до недавнего времени было на uic‘е ;(( ! Тот Perl с которым работаем в командной строке 4й версии ,а на сервере стоит 5й версии.Если ваша CGI-программа использует при этом какие-нибудь преимущества 5-й версии (например обьектно-ориентированые модули),то вы думаете отладить ее низ -ошибаетесь!.Только приготовтесь к тому, что я сейчас скажу,вы сядте,а то упадете ;)) :
Закоментируйте всю вашу программу ,т.е. перед каждой строчкой поставьте символ ‘#’. После чего,добавьте вот такие строчки: ,Должно получится так: А теперь запускайте скрипт.Естественно он выдаст Одно только слово ‘Test’. Разкоментируйте несколько строчек.Еще раз запустите скрипт.Он опять выдаст ‘Test’. Значит синтаксически эти только что разкоментированые строчки были правильные. И так далее.
Если очередной раз после раскоментирования вы запустили скрипт и получили ‘Internal Server Error’ — значит в этих строках содержалась какая-та синтаксическая ошибка. Это способ отловки синтаксических ошибок трудоемок,но к нему придется прибегнуть если ваш скрипт писан под ту версию Perl,что на сервере,а не под ту что у вас.
Узнать версию Perl можно
Ну вот мы отловили в нашем скрипте все синтаксические ошибки,он заработал, но это не значит,что он работает правильно.
Что еще можно посоветовать при отладке CGI-скриптов от ошибок возникающих во время выполнения программы. Допустим какой-то файл не открылся.Конечно показывать перепуганому пользователю эти технические подробности никчему,поэтому заведите себе специальный файл debug.txt и пусть ваши скрипты пишут в этот файл причины своих ошибок и сбоев, да и вообще о всех непредвиденых событиях.
Это можно реализовать так: Примеры использования (Напомню,что встроеная переменная Perl $! содержит сообщение о причине последней ошибки,поэтому включайте ее всегда в свои сообщения): Потом можно периодически заглядывать в этот файл debug.txt и смотреть,какие ошибки встречались при работе ваших скриптов.Таким образом ваши скрипты сами помогать будут в своей отладке ;).

Также очень может оказать помощь (может и не оказать) просмотр http‘шных логов. Все обращения к URL на сервере и все возникающие при этом ошибки идут в логи сервера httpd. Сразу хочу предупредить — размеры этих логов даже на средних размеров сервере достигает десятков мегабайт. Поэтому даже не пытайтесь их вот так просто посмотреть.- Лучше если вы уж за данное дело взялись — воспользуйтесь такими утилитами как grep,head,tail,more,less. .

Кстати я хочу сказать о причине еще одной (совсем не очевидной) ошибки.Если вы набрали скрипт у себя дома на компутере,то полученый скрипт состоит из текста в DOS‘ом формате, а не в Unix‘ом так что имейте это ввиду. Запускать вам его придется в системе Unix , так что следует перевести програмный текст в нужный формат.
Дело в том что в системах DOS и Windows (это уж очередной раз скажите все что вы думаете о Билле Гейтсе и Ко) для разделения строк используетс не один («\n»),а пара символов («\r») и («\n»). Для простых HTML-файлов это не критично — браузеры игнорируют такие символы при выводе. Но скрипт является ПРОГРАММОЙ. А в программе никаких символов возврата каретки быть не должно!! Особенно в первой строке. Потому что когда операционная система запускает скрипт, она определяет какое приложение запустить для обработки данного скрипта именно по первой строке. В первой строке как вы знаете содержится #!/usr/bin/perl или #!/usr/local/bin/perl .Поэтому при запуске скрипта mysrcipt (это кстати вы можете сами увидеть коммандами top и ps) Система запускает комманду .А теперь представьте что будет если не убрать символ возврата каретки из Windows-файла. Получиться и естественно что такого приложения нет, и следовательно попытка выполнить коммаду ни к чему не приведет.
Как с таким злом бороться я раскажу в моей следующей главе.

Trics and traps

Примеры приложений:

Кто посещает мою страничку?

Гостевая книга

Счетчик посещений

Наверное тоже одним из часто встречающихся приложений CGI являются счетчики посещений. Они стоят практически на каждой страничке, возможно даже и у вас. Но иногда вас не устраивает тот факт, что счетчик лежит где-то в другом месте.Из-за этого скажем невозможно начать счет с произвольного числа.Или еще некоторые счетчики по разному фильтруют ‘Reload’. Да и мало ли? Ну а иногда вам хочется просто сделать другой дизайн цифр. То если вы CGI-програмист то возможно имеет смысл написать свой счетчик. И делать с ним что захочется. Вот я так-же написал.
Скрипт данного счетчика обслужевает несколько счетчиков ,им вы присваиваете идентификаторы. Поэтому вы спокойно можете втыкать независимые счетчики в разные страницы сайта и даже давать это делать друзьям. В общем он прост в использовании: , Где name -любое уникальное имя идентифицирующее счетчик.Вытакже можете задать необязательный параметр dig который задает количество цифр в счетчике ,Например:

.gif‘ы в счетчике с прозрачными областями.Что дает дополнительную гибкость к примеру для улучшения внешнего вида с помощью другого фона его иногда имеет смысл запихнуть в «таблицу»:

Свои данные он пишет примерно в такой файл counter.dat: Вы спросите,зачем столько информации? Чтобы отфильтровывать нажатия Reload. Если с одного IP-адреса между заходами промежуток меньше чем 30 секунд,то счетчик не инкрементируется (Так например поступает счетчик в Rambler‘е).
Теперь об исходнике. Скрипт получился великоват,потому,что сдесь большую часть занимает генерация .gif — файлов.. Выглядит громоздко , зато пашет как трактор ;))!! Если вам циферки не понравились вы их легко сможете заменить.

Вместо заключения

Вот и подошла к концу моя книга. Надеюсь что она найдет поддержку в широких слоях интернет-сообщества.В ней я постарался изложить простым и понятным языком немного из того, что я знаю. Очень надеюсь, что я достиг своей цели (если вы дочитали мое учебное пособие до конца).И я также я очень надеюсь, что те цели которые вы перед собой ставили при прочтении данной книги станут осуществимыми. Если вы прочитали эту книгу, и вам понравилось, порекомендуйте ее своим знакомым web-дизайнерам и начинающим интернет-программистам. Для них она будет очень полезна. Также жду ваших отзывов и предложений. Я постараюсь ответить на интересующие вас вопросы. Если вам данная тема понравится, то я обязательно подумаю над тем, чтобы написать продолжение, в котором я расскажу о тех вопросах, с которыми сталкивается профессиональный интернет-программист в своей работе.
И еще раз хочу дать совет и пожелание: если что-нибудь у вас не получается, не огорчайтесь и не опускайте руки, всегда есть способ сделать любое, пусть даже с первого взгляда сложное дело. Тем более в наших руках такая мощная вещь как интернет, и от нас зависит, каким он будет через месяц, через год, через два, через десять лет. И если вы действительно приложите усилия , то ваш сайт станет достойным всеобщего восхищения.

Пример простейшего cgi сервера

Думаю многие знают, как работает CGI взаимодействие между клиентом и сервером: клиент получает от сервера и отдает серверу данные через стандартные stdin и stdout. Многие наверное даже сами писали CGI клиентов, ведь по сути — любой скрипт для веб-сервера это и есть CGI-клиент.
А многие ли задавались вопросом, как именно происходит эта «магия»? Каким образом стандартные функции для ввода/вывода вместо экрана взаимодействуют с сервером?

Результаты поиска ответа в сети меня не удовлетворили и я решил сам написать простейший CGI сервер, который сможет:

  • Запускать дочерний процес — CGI скрипт
  • Передавать скрипту переменные окружения и переменные командной строки
  • Принимать от скрипта ответ
  • Завершаться, когда завершится процесс клиента

Кроме этого, мне хотелось, чтобы клиент и сервер компилировались как в Windows, так и в Linux.

CGI-клиент

Начну я все-таки с самого простого и общеизвестного: опишу своего клиента для CGI сервера. Простой «hello world» меня не устроил, потому что нужно было проверить не только возможность передачи сообщений через stdout, но и корректность приема переменных окружения и сообщений из stdin.
Кроме этого чтобы убедиться, что получилось самое настоящее CGI взаимодействие, было решено написать не один, а сразу два клиента. На с++ и на python.

Пояснения к коду клиентов

Если из CGI-сервера запустить клиента на С++, то на экран выведется информация о переменных командной строки, три переменные окружения с именами «Content-Length», «VARIABLE2» и «VARIABLE3», а также все содержимое которое получено от сервера в stdin.
Если из CGI-сервера запустить клиента на Python, то на экран выведется информация о переменных окружения с именами «Content-Length», «VARIABLE2» и «VARIABLE3», а также все содержимое которое получено от сервера в stdin.

Надо отметить, что переменная окружения «Content-Length» должна быть сформирована сервером таким образом, чтобы быть числом меньше либо равным количеству байт в stdin. Это необходимо потому, что клиент никаким другим образом не может узнать данную информацию кроме как от сервера.

CGI-сервер

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

Пояснения к коду сервера

Сервер писался так, чтобы его можно было скомпилировать как в Windows, так и в Linux, поэтому первые несколько строк это кроссплатформенные определения.
Дальше в глобальных переменных задается:

  • тело запроса который будет послан скрипту (строка «===this is request body===\n»), длина сообщения запоминается в переменной strRequestHeader
  • переменные окружения в виде массива строк
  • переменные командной строки в виде массива <"./Main_Child.exe", «first argument», «second argument», 0>

При такой инициализации сервер будет взаимодействовать с процессом «./Main_Child.exe». Так я назвал скомпилированного клиента на С++.
Если в качестве переменных командной строки задать массив <«python», "./test.py", 0>, то сервер будет взаимодействовать со скриптом на питоне.

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

Заканчивается сервер функцией «main», большую часть которой (как можно догадаться по английским комментариям) я взял из разных сторонних источников. Из кода этой функции видно, что «вся соль» перенаправления ввода/вывода между процессами организована с помощью «pipe» (каналов).
Механизм каналов довольно простой и стандартный, он почти одинаково реализован как в Windows так и в Linux. Чтобы связать эти два подхода, в самом начале исходника я добавил простое переопределение:

В конце функции «main» организован бесконечный цикл, в котором сервер принимает от клиента ответ и передает этот ответ на экран. Выход из цикла произойдет когда клиентский процесс завершится.

Заключение

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

Zabbix 3.4: Массовый сбор данных на примерах счетчика Меркурий и smartmontools

Всем привет, ранее мы уже упоминали о возможностях по массовому сбору данных в новой версии опенсорс системы мониторинга Zabbix 3.4. Теперь остановимся на этом функционале поподробнее, и чтобы было нагляднее, расскажем о нем на двух примерах:

  • сбор всех данных за раз, полученных в JSON от консольной утилиты счетчика электроэнергии Меркурий 236
  • сбор показателей S.M.A.R.T. жестких дисков и SSD, полученных в табличном виде от smartmontools.

А в чем была собственно проблема?

Собирать данные через консольные утилиты или вызовы API данные можно было и ранее, но существовали сложности:

  • медленные запуски утилит каждый раз, на каждый нужный элемент данных
  • обращение к ресурсу (диск, порт, счетчик, API приложения) на каждый элемент данных
  • парсинг результата нужно было делать внешними скриптами/утилитами
  • а если потом нужно было поправить парсинг – приходилось опять обновлять UserParameters или скрипты
  • кроме всего прочего, одновременные запросы от нескольких Zabbix pollers приводили к ошибке при обращении, например, к последовательному порту.

В общем, дело было так:

А с появлением зависимых элементов данных, стало возможно так:

Как это работает?

  • В Zabbix 3.4 источником данных может выступать другой элемент данных, который называется родительским или мастер-элементом. Такой элемент может, например, содержать массив данных в формате JSON, XML или произвольном текстовом формате.
  • В момент поступления новых данных в родительский элемент, остальные элементы данных, которые называются зависимыми, обращаются к родительскому элементу и при помощи таких функций препроцессинга как JSON path, XPath или Regex выделяют из текста нужную метрику.

Кстати, препроцессинг – тоже нововведение 3.4, он реализован добавлением новых процессов preprocessing_manager и preprocessing_worker на Zabbix-сервере. Поэтому, если вы обновляетесь с 3.2 – не забудьте обновить шаблон для сервера, чтобы мониторить их работу.

Переходим к примерам.

Меркурий 236

Представим, что на нашем проекте, кроме контейнеров, виртуальных машин, приложений, сетевых устройств, баз данных, бизнес показателей и всего прочего требующего контроля, присутствует необходимость мониторить показатели электросети и другой «инженерки», как, например, климатическое оборудование. Используются стандартные для нашей средней полосы устройства: трехфазный счетчик электроэнергии Меркурий 236 АRT-01 PQRS с интерфейсом RS-485, поверх которого общение происходит через проприетарный протокол производителя.

Задача ответственная – сразу собирать показатели напряжения, мощности, тока, потребления, частоты. Подключить такой прибор к серверу с Zabbix агентом – задача посильная – достаточно будет серийного порта с RS-485, например, в форме USB адаптера. Но как прочитать данные? Если бы не github и добрые люди, поделившиеся своим решением для умного дома, писать бы нам модуль к Zabbix, который бы мы учили разговаривать на протоколе счетчика и опрашивать показатели.

Утилита простая и удобная (за что автору большое человеческое спасибо) подключается к счетчику на указанный порт, считывает данные и отдает нам в виде текста, CSV или JSON.

Давайте попробуем установить и запустить:

git clone https://github.com/Shden/mercury236.git
cd mercury236
make
./mercury236 /dev/ttyS0 —help
Usage: mercury236 RS485 [OPTIONS] .
RS485 address of RS485 dongle (e.g. /dev/ttyUSB0), required
—debug to print extra debug info
—testRun dry run to see output sample, no hardware required
Output formatting:
.
—help prints this screen

Запускается! Отлично, подключаем счетчик, опрашиваем, получаем JSON:

./mercury236 /dev/ttyS0 —json

В итоге утилита уже сделала всю сложную работу за нас, реализовав протокол общения с счетчиком, вытащив данные, да еще и предложила нам это в виде удобного JSON объекта. Вот только раньше просто так мы ей не смогли бы воспользоваться — пришлось бы писать обвязку в виде скриптов, а самое главное – реализовывать механизм контроля доступа к среде последовательного порта. Ведь если два поллера Zabbix одновременно обратятся к нему – один за током третьей фазы 3, а другой — за током фазы 2, у нас не вернулось бы ничего.

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

Настроим запуск утилиты mercury236 из Zabbix

sudo cp mercury236 /etc/zabbix/scripts
cd /etc/zabbix/scripts
chmod +x mercury236
sudo usermod -G dialout zabbix

Для запуска скрипта, создадим в конфиге Zabbix-агента новый UserParameter:

Сохраняем файл, не забываем перезапустить наш Zabbix-агент.

Теперь создадим в новом шаблоне родительский элемент данных:

Как видите, в родительском элементе данных нет ничего особенного – просто проверка через UserParameter Zabbix-агента. А это значит, что и нет никаких ограничений на то, какой тип проверки может выступать в роли родительского элемента – здесь могут быть и данные полученные через Zabbix trapper или через Внешние проверки. Единственное, мы выбрали Тип информации – Text и срок хранения истории в 1 день – хранить дольше мы собираемся метрики отдельно в зависимых элементах (можно не хранить данные вообще в родительском элементе, выставив срок хранения 0). Обратите внимание, что препроцессинг в этом элементе данных мы не трогаем.

Настроим получение наших метрик счетчика

Для того чтобы начать создавать зависимые элементы данных, можно воспользоваться новым помощником. Ну или просто нажать «Создать элемент данных»:


Создадим элемент данных для напряжения первой фазы, выберем:

  • Тип: Зависимый элемент данных
  • Основной элемент данных: mercury-get

Затем во вкладке «Предобработка» добавим наше выражение JSON Path:

Кстати, маленький совет. Чтобы не тратить много времени на отладку и ловлю ошибок, перед тем как заполнять JSON Path можно быстро проверить правильность выражения онлайн, например здесь: jsonpath.com, скопировав туда JSON, полученный от утилиты.

Аналогичным образом создаем другие интересующие нас метрики. В том числе — для накопленной энергии по дневному тарифу.

Для этого создадим новый элемент данных и выберем:

  • Тип: Зависимый элемент данных
  • Основной элемент данных: mercury-get

А вот во вкладке «Предобработка» обратите внимания на два нюанса:

  • будем использовать нотацию с квадратными скобками, так как в пути JSON есть дефис
  • препроцессинг может быть многошаговым, например здесь результата первого шага умножим на 1000, чтобы получить Вт*ч из кВт*ч

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

Доведем наш шаблон до ума

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

Что получилось

Шаблон готов, данные побежали, посмотрим, что у нас получилось:

Все последние данные, собранные за одно обращение:

Обратите внимание, что время сбора всех метрик абсолютно идентично.

Итоговый шаблон для счетчика доступен на репозитории решений на share.zabbix.com здесь.

  • переиспользовали хорошую программку и не тратили время на написание своей реализации сбора данных по протоколу Меркурий
  • UserParameter остался, но схлопнулся до простого вызова. По сути можно даже system.run[] использовать
  • cкрипты-обертки тоже не писали. Всё распарсили через JSON path в шаблоне
  • cчетчик не мучали сильно, один запрос – все нужные нам данные разом.

Smartctl и smartmontools

Давно мы уже писали на хабре, как можно контролировать S.M.A.R.T. жестких дисков, чтобы успеть их вовремя поменять, через использование UserParameters. Такой подход работает, но он не был лишен недостатков:

  • избыточные запуски утилиты smartctl, а она в свою очередь каждый раз обращалась к контроллеру жесткого диска
  • пришлось делать отдельный парсинг для Linux и Windows. Особенно больно с этим сейчас работать в Win: (for /F… так… экранируем двойные кавычки еще кавычками…. Аааа. )

Постараемся в 3.4 от всего этого избавится.

Случай с smartmontools имеет два отличия от примера со счетчиком выше:

  • smartctl нам JSON не возвращает
  • дисков в сервере может быть различное количество, поэтому нам нужно использовать низкоуровневое обнаружение(LLD).

Но ничего страшного! Во-первых, зависимые элементы данных работают и для LLD, а во-вторых у нас среди preprocessing-фильтров есть и PCRE regex. Воспользуемся им, чтобы вытащить нужные показатели из не супер сильно структурированного ответа утилиты. Примерно такого:

Упрощаем UserParameters

Аналогично делаем и для Windows, попутно избавляясь от CMD магии с использование for /F и find. Посмотреть можно тут.

Создаем новые родительские элементы данных

Для сбора всех атрибутов S.M.A.R.T. создадим прототип мастер-элемента данных:

Как и в предыдущем примере, ничего особенного настраивать не надо. Только Тип информации – Text, а Период хранения — 1 день.

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

Настроим получение наших атрибутов S.M.A.R.T. диска

Создадим зависимый элемент данных для атрибута 5, Reallocated:

И во вкладке «Предобработка» используем регулярное выражение:

И так же как и с JSON Path, чтобы не тратить много времени на отладку и ловлю ошибок, перед тем как заполнять regex, удобно быстро проверить правильность выражения онлайн, например здесь: regex101.com скопировав туда наш вывод smartctl.

В итоге получим такой вот список прототипов:

Тестируем, смотрим что получилось

Для SSD под Windows:

Подведем итоги примера с smartmontools:

  • мы убрали весь парсинг из UserParameters
  • нет внешних скриптов (кроме LLD), нет внешних зависимостей, весь парсинг происходит на Zabbix-сервере, там его легко посмотреть и подправить, если нужно
  • когда утилита или API не возвращает XML/JSON – не беда, всегда можно попробовать использовать регулярные выражения
  • жесткие диски больше не мучаем – сначала достаем весь список параметров S.M.A.R.T., а затем уже на Zabbix-сервере раскладываем его по метрикам.

Обновленный шаблон (заодно обновили триггеры, добавили элементы данных для SSD) доступен на репозитории решений на share.zabbix.com здесь.

В завершении

Массовой сбор метрик – простой и легкий способ уменьшить нагрузку на сеть и на ресурсы наблюдаемых систем, а также снизить потребность во внешних скриптах. Уверены, что многим пользователям Zabbix он придется по душе.

7 Приложения CGI

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

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

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

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

Что кроется за аббревиатурой CGI?

CGI — это стандартный шлюзовой интерфейс (Common Gateway Interface) для запуска внешних программ под управлением сервера WWW. Соответственно, приложениями CGI называются программы, которые, пользуясь этим интерфейсом, получают через протокол HTTP информацию от удаленного пользователя, обрабатывают ее, и возвращают результат обработки обратно в виде ссылки на уже существующий документ HTML или другой объект (например, графическое изображение) или в виде документа HTML, созданного динамически.

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

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

Когда пользователь заполняет форму и нажимает указанную кнопку, данные передаются приложению CGI, путь к которому задается в заголовке формы. Это приложение получает через протокол HTTP данные из полей формы в виде пар значений “имя поля/значение”.

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

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

Так как приложение CGI является ни чем иным, как программой, вы должны оттранслировать ее для той операционной системы, под управлением которой работает ваш сервер WWW. В некоторых случаях вы можете найти более удобным создавать программы CGI с использованием специально предназначенных для этого интерпретаторов, таких как Perl, или языка пакетных заданий. Например, вы можете создать программу CGI для сервера Microsoft Information Server как обычный пакетный файл *.bat. В нашей книге мы сконцентрируемся на использовании для создания программ CGI мобильного языка программирования C. Транслятор этого языка вы можете найти в любой операционной системе.

Создание форм

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

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

Описание формы

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


и с соответствующими параметрами.

Вот пример определения простейшей формы:

Здесь органы управления размещаются в таблице, состоящей из одного столбца и трех строк. В верхних двух строках мы разместили поля для ввода и редактирования текста, в последней строке — кнопку с названием Send. Внешний вид формы при ее просмотре в навигаторе показан на рис. 7.1.

Рис. 7.1. Простейшая форма для ввода двух текстовых строк

Перечислим допустимые параметры оператора

Форма выглядит так, как это показано на рис. 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, демонстрирующих динамическое создание документов HTML и обработку данных, введенных при помощи форм.

Программа CGIHELLO

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

Эта программа хороша для проверки возможности запуска программ CGI на вашем сервере WWW или на сервере вашего поставщика услуг Internet. Так как она очень проста, существует немного причин, по которым она могла бы не работать. Это неправильная настройка прав доступа к виртуальному каталогу, содержащему загрузочный модуль программы CGI, а также неправильная ссылка на этот каталог в параметре ACTION оператора

В этом документе определена форма, содержащая единственную кнопку, созданную оператором и имеющую тип SUBMIT.

Cgissi пример счетчика

Дурным стилем сайтостроительства считается наличие в документе гиперссылок на этот же документ. Ссылаться на самого себя неразумно — пользователь от нажатия на гиперссылку ожидает, что загрузится другая страница, а также такого рода ссылки доставляют большие неудобства пользователям каналов с низкой пропускной способностью. Такие ссылки на себя часто получаются при включении колонтитулов. Для того чтобы избежать таких ссылок, оформляйте каждый пункт меню в колонтитулах следующим образом: Данный SSI-код используется на сайте http://my-elecon.ru.

Другой не менее важный SSI-код применяется для организации версии страниц для печати. Версия страницы сайта для печати отличается от обычной страницы отсутствием колонститулов, навигации, баннеров и прочей лишней информации. Рассмотрим, как организована версия для печати на примере сайта http://alavus.ru.

При нажатии на гиперссылку «версия для печати» страница, на которой находится пользователь, перегружается. Но поскольку в строке запроса присутствует параметр for_printing, то лишний HTML-код не включается на страницу. Обратите внимание . Это строка запроса CGI-параметров. В обычном случае, у вас никаких параметров, кроме for_printing нет, но когда появляются на сайте CGI-модули, то появляются и дополнительные параметры. Забегая вперед расскажу, как делать «Версию для печати» В CGI-программе. Пока веб-сервер Apache не может обрабатывать на SSI-директивы вывод CGI-программ. Такую возможность обещают в новых версиях Apache. У CGI-программистов есть два пути либо самим разобрать SSI-директивы в файле head.inc либо, что значительно проще, создать ручками файл phead.inc и подключать его в CGI-программах.

Условные операторы записываются следующим образом: Для примера приведу SSI-код для вывода времени последней модификации документа в приемлемом виде. Как вы уже видели, команда выдает совершенно не приемлемую строчку — Monday, 26-Feb-2001 19:25:58 Московское время (зима), для размещения ее на солидном веб-сайте. Нам бы хотелось получить что-нибудь, вроде 26 Февраля 2001 года. Для этого существует команда config с параметром timefmt, которая задает формат вывода даты. Например, в нашем случае нам требуется следующий вариант , тогда результат будет 26 February 2001. Но это пока все равно не то, что бы нам хотелось. Для определения месяца мы воспользуемся условными операторами. Вот, как будет выглядеть этот код: Соответственно, чтобы получить дату в формате 26 Февраля 2001.
Вот полный список значение параметра timefmt:

Формат Описание Пример
%a Аббревиатура названия дня недели Sun
%A Полное название дня недели Sunday
%b Аббревиатура названия месяца Jan
%B Полное название месяца January
%d День месяца 01 (не 1)
%D Дата в формате «%m/%d/%y» 01/31/90
%e День месяца 1
%H Часы в 24-часовом формате 13
%I Часы в 12-часовом формате 01
%j День года 235
%m Номер месяца 01
%M Минуты 03
%p AM|PM AM
%r Время в формате «%I:%M:%S %p» 11:35:46 PM
%S Секунды 34
%s Время в секундах с 01.01.1970 957228726
%T Время в формате «%H:%M:%S» 14:05:34
%U Неделя года 49
%w Номер дня недели 5
%y Год в формате ГГ 95
%Y Год в формате ГГГГ 1995
%Z Временная зона MSK

Далее приведены несколько полезных SSI-директив. Допустим, вы распространяете какие-либо утилиты и выкладываете ссылки на файлы для скачивания. Например, такие ссылки вы найдете на сайте http://www.oxygensoftware.com. Для удобства пользователей неплохо было бы указать размер файла и иногда, дату его последней модификации. Каждый раз после выкладывания на сервер новых версий файла, модифицировать самому ручками все размеры и даты долго и мучительно. Server Side Includes приходят на помощь.

Прозрачный gif-файл
Дата модификации:
Размер: байта
Если у вас файлы больших размеров, то информацию лучше выводить в килобайтах. Для этого установите формат вывода размера файла следующим образом.
При возникновение какой-либо ошибки, например, при попытки включить в HTML-документ файл, которого не существует веб-сервер выдаст следующее сообщение:

Сообщение не слишком информативно и пугает пользователя, не так ли? Давайте изменим сообщение об ошибке следующей SSI-директивой
Теперь сообщение об ошибке вылядит так:

Илон Маск рекомендует:  attr() в CSS
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL