Общий шлюзовый интерфейс (CGI). Понятный e-commerce Суждение c board cgi

Страница 1 из 30

Сегодня такие вещи, как гостевая книга, поиск по серверу, форма для отправки сообщений - неотъемлемый атрибут практически любого серьезного сайта. Проблема внедрения этих и других прибамбасов, разумеется, всячески возбуждает воображение начинающего вебмастера, лишая его сна, аппетита и тяги к пиву. К сожалению, изучение HTML-исходников страниц конкурентов ничего, кроме ссылок на некий "cgi-bin", не дает, да еще в телеконференциях иногда встречается упоминание о каких-то cgi-скриптах. Эта статья и посвящена основам использования этих самых cgi-скриптов во славу и процветание вашего сайта.

Для начала, думаю, надо разобраться с понятиями. CGI-скрипт - это программа, которая выполняется на Web-сервере по запросу клиента (то есть посетителя Web-сайта). Программа эта принципиально ничем не отличается от обычных программ, которые установлены на вашем компьютере - будь то MS Word или игра Quake. CGI - это не язык программирования, на котором написан скрипт, а Common Gateway Interface - специальный интерфейс, с помощью которого и происходит запуск скрипта и взаимодействие с ним.

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

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

GET /~paaa/cgi-bin/guestbbok.cgi HTTP/1.0 -Вот это самое главное в запросе

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

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

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

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

cd public_html
mkdir cgi-bin
chmod 0777 cgi-bin

Последняя строчка будет очень важна.
Возьмите редактор и наберите: #!/usr/bin/perl
#first.cgi
print "Content-Type: text/html\n\n";
print "";
print "

Hello you!!!

";
print "";

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

chmod +x first.cgi

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

perl -с first.cgi

Perl вам сразу выдаст либо сообщения об ошибках(ну бывает,точку с запятой пропустили, скобочки или кавычки забыли закрыть...) это сразу по ходу дела поправимо.
Более грубая с логической точки зрения это пропустить вывод пустой строки, которая отделяет заголовок от тела:
print "Content-Type: text/html\n\n"; #Все Правильно
print "Content-Type: text/html\n"; #ОШИБКА!!!

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

Hello you!!!



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

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

Глава №9 .

Программирование с использованием CGI

Включение раздела о CGI в книгу по базам данных может показаться столь же странным, как если бы в кулинарную книгу была включена глава о ремонте автомобилей. Разумеется, для того чтобы съездить в магазин за продуктами, нужен исправный автомобиль, но уместно ли об этом говорить? Полное изложение CGI и веб-программирование в целом выходят за рамки данной книги, но краткого введения в эти темы достаточно для того, чтобы расширить возможности MySQL и mSQL по представлению данных в царстве Web.

В основном эта глава предназначена тем, кто изучает базы данных, но не прочь приобрести некоторые знания и в программировании для Web. Если ваша фамилия Бернерс-Ли или Андрессен, вряд ли вы найдете здесь то, чего еще не знаете. Но даже если вы не новичок в CGI, наличие под рукой краткого справочника во время погружения в тайны MySQL и mSQL может оказаться весьма полезным.

Что такое CGI?

Как и большинство акронимов, Common Gateway Interface (CGI - общий шлюзовый интерфейс) мало что говорит по сути. Интерфейс с чем? Где этот шлюз? О какой общности речь? Чтобы ответить на эти вопросы, вернемся немного назад и бросим взгляд на WWW в целом.

Тим Бернерс-Ли, физик, работавший в CERN, придумал Web в 1990 году, хотя план возник еще в 1988. Идея состояла в том, чтобы дать исследователям в области физики элементарных частиц возможность легко и быстро обмениваться мультимедийными данными - текстом, изображениями и звуком - через Интернет. WWW состояла из трех основных частей: HTML, URL и HTTP. HTML - язык форматирования, используемый для представления содержания в Web. URL - это адрес, используемый для получения содержимого в формате HTML (или каком-либо ином) с веб-сервера. И, наконец, HTTP - это язык, который понятен веб-серверу и позволяет клиентам запрашивать у сервера документы.

Возможность пересылки через Интернет информации всех типов явилась революцией, но вскоре была обнаружена и другая возможность. Если можно переслать через Web любой текст, то почему нельзя переслать текст, созданный программой, а не взятый из готового файла? При этом открывается море возможностей. Простой пример: можно использовать программу, выводящую текущее время, так, чтобы читатель видел правильное время при каждом просмотре страницы. Несколько умных голов в National Center for Supercomputing Applications (Национальный центр разработки приложений для суперкомпьютеров -NCSA), которые создавали веб-сервер, такую возможность увидели, и вскоре появился CGI.

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

Если CGI позволяет программам посылать данные клиенту, то формы расширяют эту возможность, позволяя клиенту посылать данные для этой CGI-программы. Теперь пользователь может не только видеть текущее время, но и устанавливать часы! Формы CGI открыли дверь для подлинной интерактивности в мире Web. Распространенные приложения CGI включают в себя:

  • Динамический HTML. Целые сайты могут генерироваться одной CGI-программой.
  • Поисковые механизмы, находящие документы с заданными пользователем словами.
  • Гостевые книги и доски объявлений, в которые пользователи могут добавлять свои сообщения.
  • Бланки заказов.
  • Анкеты.
  • Извлечение информации из размещенной на сервере базы данных.

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

Формы HTML

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

<НТМL><НЕАD><ТITLЕ>Моя страница с формами


<р>Это страница с формой.


Введите свое имя:



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


Этот тег указывает на начало формы. В конце формы требуется закрывающий тег

. Между тегами
допускаются три атрибута: ACTION задает URL или относительный путь к CGI-програм-ме, которой будут посланы данные; METHOD указывает метод HTTP, посредством которого будет послана форма (это может быть GET или ч POST, но мы почти всегда будем использовать POST); ENCTYPE задает метод кодирования данных (его следует использовать только при четком понимании того, что вы делаете).


Предоставляет наиболее гибкий способ ввода данных пользователем. Фактически есть девять разных типов тега . Тип задается атрибутом TYPE. В предыдущем примере используются два тега : один с типом SUBMIT и другой с типом по умолчанию TEXT. Девять типов следующие:

TEXT

Поле для ввода пользователем одной строки текста.

PASSWORD

To же, что TEXT, но вводимый текст не отображается на экране.

CHECKBOX

Флажок, который пользователь может устанавливать и сбрасывать.

RADIO

Радиокнопка, которая должна объединяться еще хотя бы с одной радиокнопкой. Пользователь может выбрать только одну из них.

SUBMIT

Кнопка, при нажатии которой форма отправляется на веб-сервер.

RESET

Кнопка, при нажатии которой в форме восстанавливаются значения по умолчанию.

FILE

Аналогичен текстовому окну, но предполагает ввод имени файла, который будет отправлен на сервер.

HIDDEN

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

IMAGE

Аналогичен кнопке SUBMIT, но можно задать картинку для изображения на кнопке.

Кроме атрибута TYPE теги обычно имеют атрибут NAME, связывающий введенные в поле данные с некоторым именем. Имя и данные передаются серверу в стиле величина=значение. В предыдущем примере текстовое поле именовалось firstname . Можно использовать атрибут VALUE, чтобы присвоить полям типа TEXT, PASSWORD , FILE и HIDDEN предустановленные значения. Этот же атрибут, используемый с кнопками типа SUBMIT или RESET, выводит на них заданный текст. Поля типа RADIO и CHECKBOX можно отобразить как выставленные с помощью атрибута CHECKED без задания значения.

Атрибут SIZE используется для задания длины полей типа TEXT, PASSWORD и FILE. Атрибут MAXLENGTH можно использовать для ограничения длины вводимого текста. Атрибут SRC задает URL изображения, используемого в типе IMAGE. И наконец, атрибут ALIGN задает характер выравнивания изображения для типа IMAGE и может иметь значение TOP, MIDDLE, BOTTOM (по умолчанию), LEFT или RIGHT (вверх, в середину, вниз, влево, вправо).

.

Как и у тега , у тега , и в качестве текста по умолчанию будет принят любой текст, находящийся между тегами , аналогично атрибуту VALUE для тега . Для тега

, дающая место для ввода очерка. Данные получают имя "essay". Блок текста 70 символов в ширину и 10 строк в глубину. Пространство между тегами

можно использовать для образца очерка. -->

типов "SUBMIT" и "RESET" соответственно. Кнопка "SUBMIT" имеет переопределенную надпись "Ввести данные ", а кнопка "RESET" имеет надпись по умолчанию (определяемую броузером). Кликнув по кнопке "SUBMIT", вы пошлете данные на веб-сервер, Кнопка "RESET" восстановит данные R исходное состояние, удалив все введенные пользователем данные. -->


Единственный тип ввода, который мы здесь не использовали, - это тип IMAGE для тега . Можно было бы использовать его в качестве альтернативного способа отправки формы. Однако тип IMAGE редко совместим с текстовыми и не очень чуткими броузерами, поэтому благоразумно избегать его, если только ваш сайт не выполнен в насыщенном графическом стиле.

После знакомства с основами форм HTML можно приступить к изучению собственно CGI.

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

Итак, что в точности представляет собой «набор правил», позволяющий CGI-программе, скажем, в Батавии, штат Иллинойс, обмениваться данными с веб-броузером во Внешней Монголии? Официальную спецификацию CGI наряду с массой других сведений о CGI можно найти на сервере NCSA по адресу http://hoohoo . ncsa.uluc.edu/ cgi/. Однако эта глава для того и существует, чтобы вам не пришлось долго путешествовать и самому ее искать.

Есть четыре способа, которыми CGI передает данные между CGI-npor-раммой и веб-сервером, а следовательно, и клиентом Web:

  • Переменные окружения.
  • Командная строка.
  • Стандартное устройство ввода.
  • Стандартное устройство вывода.

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

Эти данные приводятся с прикидкой на сервер HTTP Apache. Apache - наиболее распространенный веб-сервер, работающий практически на любой платформе, включая Windows 9х и Windows NT. Однако они могут быть применимы ко всем HTTP-серверам, поддерживающим CGI. Некоторые патентованные серверы, например, от Microsoft и Netscape, могут иметь дополнительные функции или работать несколько иначе. Поскольку лицо Web продолжает изменяться с невероятной скоростью, стандарты все еще развиваются, и в будущем, несомненно, произойдут изменения. Однако, что касается CGI, то эта технология представляется устоявшейся - расплачиваться за это приходится тем, что другие технологии, такие как апплеты, ее потеснили. Все CGI-программы, которые вы напишете, используя эти сведения, почти наверное смогут работать еще долгие годы на большинстве веб-серверов.

Когда CGI-программа вызывается посредством формы - наиболее распространенного интерфейса, броузер передает серверу длинную строку, в начале которой стоит путь к CGI-программе и ее имя. Затем следуют различные другие данные, которые называются информацией пути и передаются CGI-программе через переменную окружения PATH_INFO (рис. 9-1). После информации пути следует символ «?», а за ним - данные формы, которые посылаются серверу с помощью метода HTTP GET. Эти данные становятся доступными CGI-программе через переменную окружения QUERY_STRING . Любые данные, которые страница посылает с использованием метода HTTP POST, который используется чаще всего, будут переданы CGI-программе через стандартное устройство ввода. Типичная строка, которую может получить сервер от броузера, показана на рис. 9-1. Программа с именем formread в каталоге cgi-bin вызывается сервером с дополнительной информацией пути extra/information и данными запроса choice=help - по-видимому, как часть исходного URL. Наконец, данные самой формы (текст «CGI programming» в поле «keywords») пересылаются через метод HTTP POST .

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

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

имеет доступ к этим переменным так же, как и к любым переменным среды командного процессора при запуске из командной строки. В сценарии командного процессора, например, к переменной окружения F00 можно обращаться как $F00; в Perl это обращение выглядит, как $ENV{"F00"} ; в С - getenv("F00") ; и т. д. В таблице 9-1 перечислены переменные, которые всегда устанавливаются сервером - хотя бы и в значение null. Помимо этих переменных данные, возвращаемые клиентом в заголовке запроса, присваиваются переменным вида HTTP_F00 , где F00 - имя заголовка. Например, большинство веб-броузеров включает данные о версии в заголовок с именем USEfl_AGENT . Ваша CGI-npor-рамма может получить эти данные из переменной HTTP_USER_AGENT .

Таблица 9-1. Переменные окружения CGI

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

Описание

CONTENT_LENGTH

Длина данных, переданных методами POST или PUT, в байтах.

CONTENT_TYPE

Тип MIME данных, присоединенных с помощью методов POST или PUT .

GATEWAY_INTERFACE

Номер версии спецификации CGI, поддерживаемой сервером.

PATH_INFO

Дополнительная информация пути, переданная клиентом. Например, для запроса http://www.myserver.eom/test.cgi/this/is/a/ path?field=green значением переменной РАТН_ INFO будет /this/is/a/path.

PATH_TRANSLATED

То же, что PATH_INFO , но сервер производит всю


Возможную трансляцию, например, расширение имен типа «-account». »

QUERY_STRING

Все данные, следующие за символом «?» в URL. Это также данные, передаваемые, когда REQ-UEST_METHOD формы есть GET.

REMOTE_ADDR

IP-адрес клиента, делающего запрос.

REMOTE_HOST

Имя узла машины клиента, если оно доступно.

REMOTE_IDENT

Если веб-сервер и клиент поддерживают идентификацию типа identd, то это имя пользователя учетной записи, которая делает запрос.

REQUEST_METHOD

Метод, используемый клиентом для запроса. Для CGI-программ, которые мы собираемся создавать, это обычно будет POST или GET.

SERVER_NAME Имя узла - или IP-адрес, если имя недоступно, -машины, на которой выполняется веб-сервер.
SERVER_PORT Номер порта, используемого веб-сервером.
SERVER_PROTOCOL
Протокол, используемый клиентом для связи с сервером. В нашем случае этот протокол почти всегда HTTP.
SERVER_SOFTWARE Данные о версии веб-сервера, выполняющего CGI-программу.

SCRIPT_NAME

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

Приведем пример сценария CGI на Perl, который выводит все переменные окружения, установленные сервером, а также все унаследованные переменные, такие как PATH, установленные командным процессором, запустившим сервер.

#!/usr/bin/perl -w

print << HTML;

Content-type: text/html\n\n

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

HTML

foreach (keys %ENV) { print "$_: $ENV{$_}
\n"; }

print <

HTML

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

Командная строка

CGI допускает передачу CGI-программе аргументов в качестве параметров командной строки, которая редко используется. Редко используется она потому, что практические применения ее немногочисленны, и мы не будем останавливаться на ней подробно. Суть в том, что если переменная окружения QUERY_STRING не содержит символа « = », то CGI-программа будет выполняться с параметрами командной строки, взятыми из QUERY_STRING . Например, http://www.myserver.com/cgi- bin/finger?root запустит finger root на www.myserver.com.

Есть две основные библиотеки, обеспечивающие CGI-интерфейс для Perl. Первая из них - cgi-lib.pl Утилита cgi-lib.pl очень распространена, поскольку в течение долгого времени была единственной имеющейся большой библиотекой. Она предназначена для работы в Perl 4, но работает и с Perl 5. Вторая библиотека, CGI.pm, более новая и во многом превосходит cgi-lib.pl. CGI.pm написана для Perl 5 и использует полностью объектно-ориентированную схему для работы с данными CGI. Модуль CGI.pm анализирует стандартное устройство ввода и переменную QUERY_STRING и сохраняет данные в объекте CGI. Ваша программа должна лишь создать новый объект CGI и использовать простые методы, такие как paramQ, для извлечения нужных вам данных. Пример 9-2 служит короткой демонстрацией того, как CGI.pm интерпретирует данные. Все примеры на Perl в этой главе будут использовать CGI.pm.

Пример 9-2. Синтаксический анализ CGI-данных на Perl

#!/usr/bin/perl -w

use CGI qw(:standard);

# Используется модуль CGI.pm. qw(:standard) импортирует

# пространство имен стандартных CGI-функций,чтобы получить

# более понятный код. Это можно делать, если в сценарии

# используется только один объект CGI.

$mycgi = new CGI; #Создать объект CGI, который будет "шлюзом" к данным формы

@fields = $mycgi->param; # Извлечь имена всех заполненных полей формы

print header, start_html("CGI.pm test"); ft Методы "header" и "start_html",

# предоставляемые

# CGI.pm, упрощают получение HTML.

# "header" выводит требуемый заголовок HTTP, a

#"start_html" выводит заголовок HTML с данным названием,

#a также тег .

print "<р>Данные формы:
";

foreach (@fields) { print $_, ":",- $mycgi->param($_), "
"; }

# Для каждого поля вывести имя и значение, получаемое с помощью

# $mycgi->param("fieldname").

print end_html; # Сокращение для вывода завершающих тегов "".

Обработка входных данных в С

Поскольку основные API для MySQL и mSQL написаны на С, мы не будем полностью отказываться от С в пользу Perl, но там, где это уместно, приведем несколько примеров на С. Есть три широко используемые С-библиотеки для CGI-программирования: cgic Тома Бу-телла (Tom Boutell)*; cgihtml Юджина Кима (Eugene Kim)t и libcgi от EIT*. Мы полагаем, что cgic является наиболее полной и простой в использовании. В ней, однако, недостает возможности перечисления всех переменных формы, когда они не известны вам заранее. На самом деле, ее можно добавить путем простого патча, но это выходит за рамки данной главы. Поэтому в примере 9-3 мы используем библиотеку cgihtml, чтобы повторить на С приведенный выше сценарий Perl.

Пример 9-3. Синтаксический анализ CGI-данных на С

/* cgihtmltest.c - Типовая CGI-программа для вывода ключей и их значений

из данных, полученных от формы */

#include

#include "cgi-lib.h" /* Здесь содержатся все определения функций СGI */

#include "html-lib.h" /* Здесь содержатся" все определения вспомогательных функций для HTML */

void print_all(llist 1)

/* Эти функции выводят данные, переданные формой, в том же формате, что и приведенный выше сценарий Perl. Cgihtml предоставляет также встроенную функцию

Print_entries(), которая делает то же самое, используя формат списка HTML. */ {

node* window;

/* Тип "node" определен в библиотеке cgihtml и ссылается на связанный список, в котором хранятся все данные формы. */

window = I.head; /* Устанавливает указатель на начало данных формы */

while (window != NULL) { /* Пройти по связанному списку до последнего (первого пустого) элемента */

printf(" %s:%s
\n",window->entry. name,replace_ltgt(window->entry.value));

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

window = window->next; /* Перейти к следующему элементу списка. */

} }

int main() {

llist entries; /* Указатель на проанализированные данные*/

int status; /* Целое число, представляющее статус */

Html__header(); /* Вспомогательная функция HTML, выводящая заголовок HTML*/

Html_begin("cgihtml test");

/* Вспомогательная функция HTML, выводящая начало страницы HTML с указанным заголовком. */

status = read_cgi_input(&entries); /* Производит ввод и синтаксический анализ данных формы*/

Printf("<р>Данные формы:
");

Print_all(entries); /* Вызывает определенную выше функцию print_all(). */

html_end(); /* Вспомогательная функция HTML, выводящая конец страницы HTML. */

List_clear(&entries); /* Освобождает память, занятую данными формы. */

return 0; }

Стандартное устройство вывода

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

Даже если вы не используете nph -сценарий, серверу нужно дать одну директиву, которая сообщит ему сведения о вашей выдаче. Обычно это HTTP-заголовок Content-Type , но может быть и заголовок Location . За заголовком должна следовать пустая строка, то есть перевод строки или комбинация CR/LF.

Заголовок Content-Type сообщает серверу, какого типа данные выдает ваша CGI-программа. Если это страница HTML, то строка должна быть Content-Type: text/html. Заголовок Location сообщает серверу другой URL - или другой путь на том же сервере, - куда нужно направить клиента. Заголовок должен иметь следующий вид: Location: http:// www. myserver. com/another/place/.

После заголовков HTTP и пустой строки можно посылать собственно данные, выдаваемые вашей программой, - страницу HTML, изображение, текст или что-либо еще. Среди CGI-программ, поставляемых с сервером Apache, есть nph-test-cgi и test-cgi, которые хорошо демонстрируют разницу между заголовками в стилях nph и не-nph, соответственно.

В этом разделе мы будем использовать библиотеки CGI.pm и cgic, в которых есть функции для вывода заголовков как HTTP, так и HTML. Это позволит вам сосредоточиться на выводе собственно содержания. Эти вспомогательные функции использованы в примерах, приведенных ранее в этой главе.

Важные особенности сценариев CGI

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

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

Запоминание состояния

Запоминание состояния является жизненно важным средством предоставления хорошего обслуживания вашим пользователям, а не только служит для борьбы с закоренелыми преступниками, как может показаться. Проблема вызвана тем, что HTTP является так называемым протоколом «без памяти». Это значит, что клиент посылает данные серверу, сервер возвращает данные клиенту, и дальше каждый идет своей дорогой. Сервер не сохраняет о клиенте данных, которые могут понадобиться в последующих операциях. Аналогично, нет уверенности, что клиент сохранит о совершенной операции какие-либо данные, которые можно будет использовать позднее. Это накладывает непосредственное и существенное ограничение на использование World Wide Web.

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

В части клиента с появлением Netscape Navigator появилось выглядящее наспех сделанным решение под названием cookies. Оно состоит в создании нового HTTP-заголовка, который можно пересылать туда-сюда между клиентом и сервером, похожего на заголовки Content-Type и Location. Броузер клиента, получив заголовок cookie, должен сохранить в cookie данные, а также имя домена, в котором действует этот cookie. После этого всякий раз при посещении URL в пределах указанного домена заголовок cookie должен возвращаться серверу для использования в CGI-программах на этом сервере.

Метод cookie используется в основном для хранения идентификатора пользователя. Сведения о посетителе можно сохранить в файле на машине сервера. Уникальный ID этого пользователя можно послать в качестве cookie броузеру пользователя, после чего при каждом посещении сайта пользователем броузер автоматически посылает серверу этот ID. Сервер передает ID программе CGI, которая открывает соответствующий файл и получает доступ ко всем данным о пользователе. Все это происходит незаметным для пользователя образом.

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

Многие сайты по-прежнему используют cookie для персонализации страниц пользователей, но большинство дополняет их традиционным интерфейсом в стиле «имя регистрации/пароль». Если доступ к сайту осуществляется из броузера, не поддерживающего cookie, то страница содержит форму, в которую пользователь вводит имя регистрации и пароль, присвоенные ему при первом посещении сайта. Обычно эта форма маленькая и скромная, чтобы не отпугивать большинство пользователей, не заинтересованных ни в какой персонализации, а просто желающих пройти дальше. После ввода пользователем в форму имени регистрации и пароля CGI находит файл с данными об этом пользователе, как если бы имя посылалось с cookie. Используя этот метод, пользователь может регистрироваться на персонализированном веб-сайте из любой точки света.

Помимо задач учета предпочтений пользователя и длительного хранения сведений о нем можно привести более тонкий пример запоминания состояния, который дают популярные поисковые машины. Осуществляя поиск с помощью таких служб, как AltaVista или Yahoo, вы обычно получаете значительно больше результатов, чем можно отобразить в удобном для чтения виде. Эта проблема решается тем, что показывается небольшое количество результатов - обычно 10 или 20 - и дается какое-либо средство перемещения для просмотра следующей группы результатов. Хотя обычному путешественнику по Web такое поведение кажется обычным и ожидаемым, действительная его реализация нетривиальна и требует запоминания состояния.

Когда пользователь впервые делает запрос поисковому механизму, тот собирает все результаты, возможно, ограничиваясь некоторым предустановленным предельным количеством. Фокус состоит в том, чтобы выдавать эти результаты одновременно в небольшом количестве, запомнив при этом, что за пользователь запрашивал эти результаты и какую порцию он ожидает следующей. Оставляя в стороне сложности самого поискового механизма, мы встаем перед проблемой последовательного предоставления пользователю некоторой информации по одной странице. Рассмотрим пример 9-4, в котором показан сценарий CGI, выводящий десять строк файла и предоставляющий ему возможность просмотреть следующие или предыдущие десять строк.

Пример 9-4. Сохранение состояния в сценарии CGI

#!/usr/bin/perl -w

use CGI;

Open(F,"/usr/dict/words") or die("He могу открыть! $!");

#Это файл, который будет выводиться, может быть любым.

$output = new CGI;

sub print_range { # Это главная функция программы, my $start = shift;

# Начальная строка файла, my $count = 0;

# Указатель, my $line = "";

# Текущая строка файла, print $output->header,

$output->start_html("Moй словарь");

# Создает HTML с заголовком "Мой словарь", print "\n";

while (($count < $start) and ($line = )) { $count++; }

# Пропустить все строки перед начальной, while (($count < $start+10) and ($line ? )) { print $line; $count++; }

# Напечатать очередные 10 строк.

my $newnext = $start+10; my $newprev = $start-10;

# Установить начальные строки для URL "Next" и "Previous",

print "

";

unless ($start == 0) { # Включить URL "Previous", если только вы

# уже не в начале.

print qq%Previous%; }

unless (eof) { # Включить URL "Next", если только вы # не в конце файла.

print qq% Next%;

}

print «HTML; HTML

exit(0); }

# Если данных нет, начать сначала,

if (not $output->param) {

&print_range(0); }

# Иначе начать со строки, указанной в данных.

&print_range($output->param("start"));

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

Однако если вам требуется нечто большее, чем возможность просто листать "файл, то полагаться на URL бывает обременительно. Облегчить эту трудность можно через использование формы HTML и включение данных о состоянии в теги типа HIDDEN. Этот метод с успехом используется на многих сайтах, позволяя делать ссылки между взаимосвязанными CGI-программами или расширяя возможности использования одной CGI-программы, как в предыдущем примере. Вместо ссылки на определенный объект, такой как начальная страница, данные URL могут указывать на автоматически генерируемый ID пользователя.

Так работают AltaVista и другие поисковые машины. При первом поиске генерируется ID пользователя, который скрыто включается в последующие URL. С этим ID связаны один или несколько файлов, содержащих результаты запроса. В URL включаются еще две величины: текущее положение в файле результатов и направление, в котором вы хотите перемещаться в нем дальше. Эти три значения - все, что нужно для работы мощных систем навигации больших поисковых машин.

Впрочем, не хватает еще кое-чего. Использовавшийся в нашем примере файл /usr/diet/words очень велик. Что если на середине чтения мы его бросим, но захотим вернуться к нему позднее? Если не запомнить URL следующей страницы, никакого способа вернуться назад нет, даже AltaVista это не позволит. Если вы перезагрузите свой компьютер или станете работать с другого, невозможно вернуться к результатам прежнего поиска, не вводя заново запрос. Однако такое долговременное запоминание состояния лежит в основе персонализации вебсайтов, о которой мы говорили выше, и стоит посмотреть, как им можно воспользоваться. Пример 9-5 является модифицированным вариантом примера 9-4.

Пример 9-5. Устойчивое запоминание состояния

#!/usr/bin/perl -w

use CGI;

umask 0;

Open(F,"/usr/dict/words") or die("He могу открыть! $!");

Chdir("users") or die("He могу перейти в каталог $!");

# Это каталог, где будут храниться все данные

# о пользователе.

Soutput = new CGI;

if (not$output->param) {

print $output->header,

$output->start_html("Мой словарь");

print «HTML;


<р>Введите свое имя пользователя:


HTML

exit(0); }

$user = $output->param("username");

## Если файла пользователя нет, создать его и установить

## начальное значение в "0",

if (not -e "$user") {

open (U, ">$user") or die("He могу открыть! $!");

print U "0\n";

close U;

&print_range("0");

## если пользователь существует и в URL не задано

## начальное значение, прочесть последнее значение и начать с него.

} elsif (not $output->param("start")) {

Open(U,"Suser") or die("He могу открыть пользователя! $!");

$start = ; close U;

chomp $starl;

uprint range($start);

## Если пользователь существует и в URL не указано

## начальное значение, записать начальное значение

## в файл пользователя и начать вывод.

} else{

Open(U,">$user") or die("He могу открыть пользователя для записи! $!");

print U $output->param("start"), "\n";

close U;

&print_range($output->param("start 1)); }

sub print_range {

my $start = shift;

my $count = 0;

my $line = " "

print $output->header,

$output->start_html(" Мой словарь ");

print "

\n";

while (($count < $start) and ($line = )) { $count++; }

while (($count < $start+10) and ($line = ))

print $line; $count++;

my $newnext = $start+10;

my $newprev = $start-10;

print "

unless (Sstart == 0)

{

print

qq%

Previous%;

}

unless (eof) { print qq% Next%;

# Заметьте, что имя пользователя "username" добавлено к URL.

# В противном случае CGI забудет, с каким пользователем имел дело.

}

print $output->end_html;

exit(0");

}

Меры безопасности

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

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

#!/usr/bin/perl -w

use CGI;

my $output = new CGI;

my $username = $output»param("username");

print $output->header, $output->start_html("Finger Output"),

"

",
 "finger $username", "
", $output->end_html;

Эта программа обеспечивает действующий CGI-интерфейс к команде finger. Если запустить программу просто как finger.cgi, она выведет список всех текущих пользователей на сервере. Если запустить ее как finger.cgi?username=fred, то она выведет информацию о пользователе «fred» на сервере. Можно даже запустить ее как finger. cgi?userna-me=bob@f oo.com для вывода информации об удаленном пользователе. Однако если запустить ее как finger.cgi?username=fred;[email protected]могут произойти нежелательные вещи. Оператор обратный штрих «"" » в Perl порождает процесс оболочки и выполняет команду, возвращающую результат. В данной программе "finger $username* используется как простой способ выполнить команду finger и получить ее результат. Однако большинство командных процессоров позволяет объединять в одной строке несколько команд. Например, любой процессор, подобный процессору Борна, делает это с помощью символа «; ». Поэтому "finger fred;mail [email protected]запустит сначала команду finger, а затем команду mail [email protected]которая может послать целиком файл паролей сервера нежелательному пользователю.

Одно из решений состоит в синтаксическом анализе поступивших от формы данных с целью поиска злонамеренного содержания. Можно, скажем, искать символ «;» и удалять все следующие за ним символы. Можно сделать такую атаку невозможной, используя альтернативные методы. Приведенную выше CGI-программу можно переписать так:

#!/usr/local/bin/perl -w

use CGI;

my $output = new CGI;

my $username = $output->param("username");

$|++;

# Отключить буферизацию с целью направления всех данных клиенту,

print $output->header, $putput->start_html("Finger Output"), "

\n";

$pid = open(C_OUT, "-|");# Эта идиома Perl порождает дочерний процесс и открывает

# канал между родительским и дочерним процессами,

if ($pid) {# Это родительский процесс.

print ; ft Вывести выходные данные дочернего процесса.

print "

", $output->end_html;

exit(O); ft Завершить программу. }

elsif (defined $pid) { # Это дочерний процесс.

$|++; # Отключить буферизацию.

ехес("/usr/bin/finger",$username) or die("exec() call failed.");

# Выполняет программу finger с Susername в качестве одного единственного
# аргумента командной строки. } else { die("неудачная попытка fork()"); }

# Проверка ошибок.

Как видите, это не на много более сложная программа. Но если запустить ее как finger.cgi?username=fred;[email protected]то программа finger будет выполняться с аргументом fred;mail [email protected]как одним именем пользователя.

В качестве дополнительной меры безопасности этот сценарий запускает finger явно как /usr/bin/finger. В маловероятном случае, когда веб-сервер передает вашей CGI-программе необычный PATH, запуск просто finger может заставить выполниться не ту программу, которая нужна. Еще одну меру безопасности можно принять, изучив переменную окружения PATH и убедившись, что она имеет приемлемое значение. Неплохо удалить из PATH текущий рабочий каталог, если только вы уверены, что это не тот случай, когда действительно нужно выполнить находящуюся в нем программу.

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

Однако работа в качестве пользователя с ограниченными правами ограничивает и возможности CGI. Если программе CGI нужно читать или записывать файлы, она может делать это только там, где у нее есть такое разрешение. Например, во втором примере запоминания состояния для каждого пользователя ведется файл. CGI-программа должна иметь разрешение на чтение и запись в каталоге, содержащем эти файлы, не говоря уже о самих файлах. Это можно сделать, создав каталог в качестве того же пользователя, что и сервер, с правами чтения и записи только для этого пользователя. Однако для такого пользователя, как «nobody», только root имеет подобную возможность. Если вы не суперпользователь, то вам придется общаться с администратором системы при каждом изменении в CGI.

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

Если это ваше первое обращение к CGI-программированию, дальнейшее изучение можно продолжить разными путями. По этому предмету написаны десятки книг, многие из которых не предполагают никакого знакомства с программированием. «CGI Programming on the World Wide Web» издательства O"Reilly and Associates охватывает материал от простых сценариев на разных языках до действительно поразительных трюков и ухищрений. Общедоступная информация имеется также в изобилии в WWW. Неплохо начать с CGI Made Really Easy (Действительно просто о CGI) по адресу http://www.jmarshall.com/easy/cgi/ .

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

С начала эпохи Интернет базы данных взаимодействовали с разработкой World Wide Web. На практике многие рассматривают Web просто как одну гигантскую базу данных мультимедийной информации.

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

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

Одна из причин подключения баз данных к Web регулярно дает о себе знать: значительная часть мировой информации уже находится в базах данных. Базы данных, существовавшие до возникновения Web, называются унаследованными (legacy) базами данных (в противоположность неподключенным к Web базам данных, созданным в недавнее время и которые следует назвать «дурной идеей»). Многие корпорации (и даже частные лица) стоят сейчас перед задачей обеспечения доступа к этим унаследованным базам данных через Web. Если только ваша унаследованная база не MySQL или mSQL, эта тема лежит за пределами данной книги.

Как сказано раньше, только ваше воображение может ограничить возможности связи между базами данных и Web. В настоящее время существуют тысячи уникальных и полезных баз данных, имеющие доступ из Web. Типы баз данных, действующих за пределами этих приложений, весьма различны. Некоторые из них используют CGI-программы в качестве интерфейса с сервером баз данных, таким как MySQL или mSQL. Эти типы представляют для нас наибольший интерес. Другие используют коммерческие приложения для взаимодействия с популярными настольными базами данных, такими как Microsoft Access и Claris FileMaker Pro. А другие просто работают с плоскими текстовыми файлами, являющимися самыми простыми базами данных изо всех возможных.

С помощью этих трех типов баз данных можно разрабатывать полезные веб-сайты любого размера и степени сложности. Одной из наших задач на протяжении нескольких следующих глав будет приложение мощи MySQL mSQL к Web с использованием CGI-программирования.

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

Интернет доказал, что является идеальной средой для распределения информации, как видно по его огромной популярности и масштабного развития. Хотя кое-кто подвергает сомнению полезность Интернета и приписывают ее широкое развитие и популярность главным образом навязчивой рекламе, Интернет бесспорно является важным средством представления всевозможных видов информации. Мало того, что существует множество услуг по предоставлению самой свежей информации (новости, погода, спортивные события в реальном времени) и материалов справочного характера в электронном виде, предлагаются также значительные объемы данных другого рода. Налоговое управление США, которое распространило все свои бланки налоговых деклараций в 1995 году и другую информацию через Всемирную паутину, недавно призналось о получении писем от поклонников своего Веб-сайта. Кто бы мог подумать, что Налоговое управление когда-нибудь будет получать письма от поклонников? Это произошло не от того, что его сайт был хорошо оформлен, а потому что он оказался по-настоящему полезным инструментом для тысяч, а возможно и миллионов людей.

Что делает Веб уникальным и таким привлекательным информационным сервисом? Прежде всего тем, что он предоставляет интерфейс гиперсреды для данных. Вспомните дисковод жесткого диска своего компьютера. Как правило, данные выражаются в линейном виде, аналогично файловой системе. Например, Вы имеете ряд папок, а внутри каждой папки находятся либо документы либо другие папки. Веб использует разную парадигму для выражения информации называемой гиперсредой. Гипертекстовый интерфейс состоит из документа и связей. Связи - это слова, на которые кликают, чтобы увидеть другие документы или отыскать другие виды информации. Веб расширяет концепцию гипертекста, включив другие типы носителей, например графику, звуки, видео (отсюда имя "гиперсреда"). Выделение текста или графики на документе позволяет увидеть связанную информацию о выделенном элементе в любом количестве форм.

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

Хотя Веб предоставляет для информации уникальный интерфейс гиперсреды, имеется много других эффективных способов распределения данных. Например, сетевые услуги типа Протокола передачи файлов (FTP) и группа новостей "Gopher" существовали намного раньше появления Всемирной паутины. Электронная почта была первичной средой для связи и обмена информацией по Интернету и большинством других сетей почти с самого начала функционирования этих сетей. Почему Интернет стал таким популярным способом распределения информации? Мультимедийный аспект Интернета внес ощутимый вклад в его небывалый успех, но для того, чтобы Интернет стал наиболее эффективным он должен быть интерактивным.

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

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

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

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

Что такое CGI?

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

Обычно, для расширения возможностей сервера, Вам пришлось бы самому модифицировать сервер. Такое решение нежелательно, потому что это требует понимания нижнего уровня сетевого программирования по протоколу Интернета. Это также требовало бы редактирования и перекомпиляции исходного кода сервера или записи пользовательского сервера для каждой задачи. Допустим, нужно расширить возможности сервера так, чтобы он действовал как шлюз Web-to-e-mail (от Веб к эл.почте), отбирая информацию, введенную пользователем, из браузера и посылая ее по электронной почте другому пользователю. В сервер пришлось бы вставить код для анализа ввода от браузера, пересылки бы его по электронной почте другому пользователю, и пересылке ответа назад в браузер через сетевое соединение.

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

Во-вторых, это трудно и требует обширных технических знаний.

В-третьих, это применимо только для конкретного сервера. Если нужно переместить ваш сервер на другую платформу, придется запустить или по крайней мере потратить много времени, занимаясь переносом кода на эту платформу.

Почему CGI?

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

Связь CGI осуществляется стандартным вводом и выводом, что означает, что, если Вы знаете, как печатать и читать данные, используя свой язык программирования, можно написать приложение сервера Веб. Помимо анализа ввода и вывода, программирование приложений CGI почти эквивалентно программированию любого другого приложения. Например, для программирования программы "Hello, World!", используются функции печати вашего языка и формат, определенный для программ CGI, чтобы напечатать соответствующее сообщение.

Выбор языка програмирования

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

  • Печатать в стандартном выводе
  • Читать со стандартного ввода
  • Читать с переменных режимов

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

Языки подпадают под один из следующих двух классов: транслируемый и интерпретируемый. Транслируемый язык -например, C или C++ обычно меньше и быстрее, в то время как интерпретируемые языки, такие как Perl или Rexx, иногда требуют загрузки большого интерпретатора после запуска. Дополнительно, Вы можете распределять двоичные коды (код, транслируемый в машинный язык) без исходного кода, если ваш язык транслируемый. Распределение интерпретируемых сценариев обычно означает распределение исходнго кода.

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

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

Какой язык является наиболее подходящим для программирования CGI? Тот, который Вы считаете для себя более удобным с точки зрения программирования. Оба одинаково эффективны для программирования приложений CGI, и с надлежащими библиотеками, оба имеют схожие возможности. Однако, если Вы имеете труднодоступный сервер, можно использовать меньшие транслируемые программы C. Если Вы должны быстро написать приложение, которое требует значительной работы по обработке текста, можно вместо него использовать Perl.

Предостережения

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

Вряд ли. CGI имеет несколько преимуществ перед более новыми технологиями.

  • Он универсален и переносим. Вы можете написать приложение CGI, используя практически любой язык программирования на любой платформе. Некоторые из альтернатив, такие как API сервера, ограничивают Вас некоторыми языками и намного сложны для изучения.
  • Маловероятно что, клиентские технологии типа Java, заменят CGI, потому что имеются некоторые приложения, для которых серверные приложения намного лучше подходят для выполнения.
  • Многие из ограничений CGI - это ограничения HTML или HTTP. По мере развития стандартов Интернета в целом, развиваются и возможности CGI.

Резюме

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

Глава 2. Основы

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

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

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

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

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

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

  • Традиционная программа " Hello, World!";
  • Вывод CGI: отсылка информации назад для отображения в Интернет-браузере;
  • Конфигурирование, установка, и выполнение приложения. Вы узнаете о различных платформах и серверах Веб;
  • Ввод CGI: интерпретация информации, посланной браузером Веб. Ознакомление с некоторыми полезными библиотеками программирования для анализа такого ввода;
  • Простой пример: он охватывает все уроки данной главы;
  • Стратегия программирования.

Из-за характера данной главы, я только слегка касаюсь некоторых тем. Не волнуйтесь; все эти темы рассматриваются гораздо глубже в других главах.

Hello, World!

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

CGI независит от языка, так что Вы можете реализовать эту программу на любом языке. Здесь используется несколько различных языков, чтобы продемонстрировать независимость каждого языка. В языке Perl, программа " Hello,World!" показана в листинге 2.1.

Листинг 2.1. Hello, World! в Perl. #!/usr/local/bin/perl # Hello.cgi - Моя первая программа CGI print "Content-Type: text/html\n\n"; print " \n"; print "Hello, World!"; print "\n"; print "\n"; print "

Hello, World!

\n"; print " \n";

Сохраните эту программу как hello.cgi, и установите ее в соответствующем месте. (Если Вы не уверены, где оно находится, не беспокойтесь; Вы узнаете это в разделе "Установка и выполнение программы CGI " ниже в данной главе.) Для большинства серверов нужный каталог называется cgi-bin. Теперь, вызовите программу из вашего браузера Веб. Для большинства, это означает открыть следующий универсальный указатель ресурса (URL):

http://hostname/directoryname/hello.cgi

Hostname - имя вашего сервера Веб, и directoryname - каталог, в который Вы помещаете hello.cgi (вероятно cgi-bin).

Разбиение hello.cgi

Следует отметить несколько моментов относительно hello.cgi.

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

Во-вторых, обратите внимание на то, что содержание первого оператора печати (Content-Type: text/html) не появляется на вашем браузере Веб. Вы можете отослать любую информацию, по Вашему усмотрению, назад на браузер (страницу HTML, графику или звук), но сначала, нужно сообщить браузеру какого вида данные вы ему посылаете. Эта строка сообщает браузеру какой вид информации ожидать - в данном случае, страницу HTML.

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

В общем, hello.cgi состоит из двух основных частей:

  • сообщает браузеру какую информацию ожидать (Content-Type: text/html)
  • сообщает браузеру, что отобразить (Hello, World!)

Hello, World! в C

Чтобы показать независимость программ CGI от языков, в листинг 2.2 показан эквивалент программы hello.cgi , написанной в C.

Листинг 2.2. Hello, World! в C. /* hello.cgi.c - Hello, World CGI */ #include int main() { printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("Hello, World!\n"); printf("\n"); printf("\n"); printf("

Hello, World!

\n"); printf(" \n"); }

Примечание

Обратите внимание на то, что версия Perl hello.cgi использует Content-Type print ": text/html\n\n "; В то время как версия C использует Printf (" Content-Type: text/html\r\n\r\n ");

Почему Perl печатает операторный конец с двумя символами новой строки (\n), в то время как C printf заканчивается двумя символами возврата каретки и новой строки(\r\n)?

Формально, заголовки (весь вывод перед пустой строкой) как предполагается, будут отделены символом возрата каретки и новой строки. К сожалению, на машинах DOS и Windows, Perl транслирует \r как другую новую строку, а не как перевод каретки.

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

Соответствующее решение этой проблемы представлено в Главе 4, "Вывод".

Ни серверу Веб, ни браузеру не важно, какой язык используется для записи программы. Хотя каждый язык имеет преимущества и недостатки в качестве языка программирования CGI, лучше использовать язык, с которым Вам удобнее всего работать. (Более детально выбор языка программирования обсуждается в Главе 1 "Общешлюзовой интерфейс (CGI) ").

Выведение CGI

Теперь можно внимательнее изучить вопрос отправки информации на браузер Веб. Из примера " Hello, World!", видно, что браузеры Веб ожидают два набора данных: заголовок, который содержит информацию, например какую информацию отобразить (например Content-Type: line) и фактическую информацию (что отображается на браузере Веб). Эти два блока информации отделены пустой строкой.

Заголовок называется заголовком HTTP. Он дает важные сведения об информации, которую браузер собирается получать. Имеются несколько различных типов заголовков HTTP, и наиболее универсальным является тот, который Вы использовали раньше: Content-Type: заголовок. Вы можете использовать различные комбинации заголовков HTTP, отделяя их символами возврата каретки и новой линии (\r\n). Пустая строка, отделяющая заголовок от данных, также состоит из возврата каретки и новой строки (почему нужны оба, кратко описано в предшествующем примечании и подробно в Главе 4). Вы узнаете о других заголовках HTTP в Главе 4; в данный момент Вы занимаетесь Content-Type: заголовок.

Content-Type: заголовок описывает тип данных, которые возвращает CGI. Соответствующим форматом для этого заголовка является:

Content-Type: subtype/type

Где subtype/type - правильный тип многоцелевых расширений почты Интернета (MIME). Наиболее распространенным типом MIME является тип HTML: text/html. В таблице 2.1 приведено еще несколько распространненых типов MIME, которые будут рассмотрены; более полный перечень и анализ типов MIME приводится в Главе 4.

Примечание

MIME было первоначально изобретено для описания содержания тел сообщений почты. Оно стало довольно распространненым способом представления информации о Content-Type . Вы можете узнать больше о MIME в RFC1521. RFCs в Интернете обозначают "Просьбы о комментариях", которые представляют собой резюме решений, принятых группами в Интернете, пытающимися установить стандарты. Можно посмотреть результаты RFC1521 на следующем адресе: http://andrew2.andrew.cmu.edu/rfc/rfc1521.html

Таблица 2.1. Некоторые общие типы MIME. Тип MIME Описание Text/html Язык разметки гипертекста (HTML) Text/plain Простые текстовые файлы Image/gif Графические файлы GIF Image/jpeg Сжатые графические файлы JPEG Audio/basic Аудио - файлы Sun *.au Audio/x-wav Файлы Windows *.wav

После заголовка и пустой строки, Вы просто печатаете данные в нужном для Вас виде. Если Вы посылаете HTML, то печатайте теги HTML и данные к stdout после заголовка. Вы можете послать также графику, звук и другие двоичные файлы, просто печатая содержимое файла в stdout. Несколько примеров этого приведено в Главе 4.

Установка и выполнение программы CGI

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

Все серверы требуют пространства для файлов сервера и пространства для документов HTML. В настоящей книге, область сервера называется ServerRoot, а область документа - DocumentRoot. На машинах UNIX ServerRoot - обычно в /usr/local/etc/httpd/, а DocumentRoot - обычно в /usr/local/etc/httpd/htdocs/. Однако, это не имеет никакого значения для вашей системы, поэтому замените все ссылки на ServerRoot и DocumentRoot на ваши собственные ServerRoot и DocumentRoot.

Когда Вы обращаетесь к файлам, используя ваш браузер Веб, Вы определяете файл в URL относительно DocumentRoot. Например, если адрес вашего сервера mymachine.org, то Вы обращаетесь к этому файлу со следующим URL: http://mymachine.org/index.html

Конфигурирование сервера для CGI

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

  • Обозначенный каталог. Некоторые серверы позволяют определить, что все файлы в обозначенном каталоге (обычно, по умолчанию, называемый cgi-bin) являются CGI.
  • Расширения имени файла. Много серверов имеют такую предварительную конфигурацию, которая позволяет определять все файлы заканчивающиеся на.cgi, как CGI.

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

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

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

Предостережение

Помните о важности вопросов защиты, когда Вы конфигурируете ваш сервер для CGI. Некоторые подсказки будут рассмотрены здесь, а в Главе 9 "Защита CGI" эти аспекты рассматриваются более подробно.

Установка CGI на серверах UNIX

Независимо от того, как конфигурирован ваш сервер UNIX, нужно предпринять несколько шагов, чтобы удостовериться в том, что ваши приложения CGI выполняются должным образом. Ваш сервер Веб обычно будет работать как несуществующий пользователь (то есть пользователь UNIX nobody - учетная запись, которая не имеет прав доступа к файлу и не может быть зарегистрирована). Сценарии CGI (написанные на Perl, оболочке Bourne или на другом языке описания сценария) должны быть, выполнимы и читаемы по всему миру.

Подсказка

Чтобы сделать ваши файлы читаемыми и выполнимым по всему миру, используйте следующую команду UNIX права доступа: chmod 755 имени файла.

Если Вы используете язык описания сценария типа Perl или Tcl, укажите полный путь вашего интерпретатора в первой строке вашего сценария. Например, сценарий Perl, использующий perl в каталоге /usr/local/bin должен начинаться со следующей строки:

#!/usr/local/bin/perl

Предостережение

Никогда не помещайте интерпретатор (perl, или двоичный код Tcl Wish в каталог /cgi-bin. Это создает опасность для защиты в Вашей системе. Более подробно это описано в Главе 9.

Некоторые универсальные cерверы UNIX

Серверы NCSA и Apache имеют файлы со сходной конфигурацией, потому что сервер Apache был первоначально основан на коде NCSA. По умолчанию, они конфигурированы таким образом, чтобы любой файл в каталоге cgi-bin (расположенный по умолчанию в ServerRoot) являлся программой CGI. Чтобы изменить местоположение каталога cgi-bin, можно отредактировать файл конфигурации conf/srm.conf. Форматом для конфигурирования этого каталога является

ScriptAlias fakedirectoryname realdirectoryname

где fakedirectoryname - псевдо-имя каталога (/cgi-bin), и realdirectoryname - полный путь, где программы CGI фактически сохранены. Вы можете конфигурировать более одного ScriptAlias, добавляя еще строки ScriptAlias.

Заданная по умолчанию конфигурация достаточна для потребностей большинства пользователей. Нужно отредактировать строку в файле srm.conf в любом случае, чтобы определить правильное realdirectoryname. Если, например, Ваши программы CGI расположены в /usr/local/etc/httpd/cgi-bin, строка ScriptAlias в вашем файле srm.conf должна походить на следующую:

ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/

Чтобы обращаться или ссылаться на программы CGI, расположенные в этом каталоге, используется следующий URL:

Http://hostname/cgi-bin/programname

Где hostname - имя хозяина вашего сервера Веб, и programname - имя Вашего CGI.

Например, допустим, что Вы скопировали программу hello.cgi в Ваш каталог cgi-bin (например, /usr/local/etc/httpd/cgi-bin) на Вашем сервере Веб, называемом www.company.com. Чтобы обратиться к вашему CGI, используйте следующий URL: http://www.company.com/cgi-bin/hello.cgi

Если нужно конфигурировать сервер NCSA или Apache так, чтобы распознавать любой файл с расширением.cgi как CGI, нужно отредактировать два файла конфигурации. Сначала, в файле srm.conf, не комментируйте следующую строку:

AddType application/x-httpd-cgi .cgi

Это свяжет CGI типа MIME с расширением.cgi. Теперь, нужно изменить файл access.conf, чтобы можно было выполнить CGI в любом каталоге. Для этого, добавьте опцию ExecCGI к строке Option. Это будет выглядеть примерно как следующая строка:

Option Indexes FollowSymLinks ExecCGI

Теперь, любой файл с расширением.cgi считается CGI; обращайтесь к нему, как обращались бы к любому файлу на вашем сервере.

Сервер CERN конфигурирован так же, как и серверы Apache и NCSA. Вместо ScriptAlias, сервер CERN использует команду Exec. Например, в файле httpd.conf, Вы увидете следующую строку:

Exec /cgi-bin/* /usr/local/etc/httpd/cgi-bin/*

Другие серверы UNIX можно конфигурировать таким же способом; более подробно об этом описано в документации сервера.

Установка CGI на Windows

Большинство серверов, доступных для Windows 3.1, Windows 95 и Windows NT конфигурировано с помощью метода "расширение имени файла" для распознавания CGI. Вообще, изменение конфигурации сервера на базе Windows просто требует выполнения программы конфигурации сервера и внесения соответствующих изменений.

Иногда конфигурирование сервера для правильного выполнения сценарий (типа Perl) представляется сложным делом. В DOS или Windows, Вы не сможете определить интерпретатор на первой строке сценария, как это происходит при работе с UNIX. Некоторые серверы имеют заранее заданную конфигурацию, чтобы связать некоторые расширения имени файла с интерпретатором. Например, многие Веб-серверы Windows предполагают, что файлы, оканчивающиеся на.pl, являются сценариями Perl.

Если сервер не выполняет такой тип ассоциации файла, можно определить пакетный файл упаковщика, который вызывает как иинтерпретатор, так и сценарий. Как и с сервером UNIX, не устанавливайте интерпретатор ни в каталоге cgi-bin ни в каком-либо Веб-доступном каталоге.

Установка CGI на Macintosh

Две наиболее известные опции сервера для Macintosh - это WebStar StarNine и его предшественник MacHTTP. Оба распознают CGI по расширению имени файла.

MacHTTP понимает два различных расширения: .cgi и.acgi, который обозначает асинхронный CGI. Регулярные программы CGI, установленные на Macintosh (с расширением.cgi), будут поддерживать Веб-сервер в состоянии занятости, пока не закончится выполнение CGI, вынуждая сервер приостановить выполнение всех других запросов. Асинхронный CGI, с другой стороны, позволяет серверу принимать запросы даже во время своей работы.

Разработчик CGI Macintosh, использующий любой из этих Веб-серверов, должен, по возможности, использовать просто расширение.acgi, а не расширение.cgi. Оно должно работать с большинством программ CGI; если оно не работает, переименуйте программу на.cgi.

Выполнение CGI

После того, как вы установили CGI, имеются несколько способов выполнить его. Если ваш CGI -программа, работающая только с выводом, типа программы Hello,World!, тогда Вы может выполнять ее, просто обращаясь к ее URL.

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

Быстрая обучающая программа по формам HTML

Два наиболее важных тега в форме HTML - это теги и . Можно создавать большинство форм HTML, используя только эти два тега. В данной главе, Вы изучите эти теги и небольшое подмножество возможных типов или атрибутов . Полное руководство и ссылка на формы HTML находятся в Главе 3 " HTML и формы" .

Тег

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

Следующая строка показывает спецификации для тега :

< ACTION FORM = "url" METHOD = ENCTYPE = "..." >

Атрибут ENCTYPE не играет особой роли и обычно не включается с тегом . Подробная информация относительно тега ENCTYPE дана в Главе 3. Один из способов использования ENCTYPE, показан в Главе 14 "Фирменные расширения. "

Атрибут ACTION ссылается на URL программы CGI. После того, как пользователь заполнит форму и предоставит информацию, вся информация кодируется и передается программе CGI. Программа CGI решает сама вопрос о декодировании и обработке информации; этот аспект рассматривается в "Принятие ввода от браузера, " ниже в настоящей главе.

Наконец, атрибут METHOD описывает, как программа CGI должна получать ввод. Эти два методы - GET и POST - отличаются в отношении того, как передавать информацию программе CGI. Оба обсуждены в "Принятие ввода от браузера. "

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

для обозначения конца формы. Нельзя иметь форму внутри формы, хотя Вы можете установить форму, которая позволяет представлять части информации в различные местах; этот аспект широко рассматривается в Главе 3.

Тег

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

< INPUT TYPE=text NAME = "... " VALUE = "... " SIZE = MAXLENGTH = >

NAME - символическое имя переменной, которая содержит значение, введенное пользователем. Если Вы включаете текст в атрибут VALUE, этот текст будет помещен как заданный по умолчанию в поле текстового ввода. Атрибут SIZE позволяет Вам определить горизонтальную длину поля ввода, поскольку он будет появляться в окне браузера. И наконец, MAXLENGTH определяет максимальное число символов которые, пользователь может ввести в поле. Обратите внимание, что атрибуты VALUE, SIZE, MAXLENGTH являются необязательными.

Представление формы

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

< Input type=submit >

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

Принятие ввода от браузера

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

Программа CGI получает два вида информации от браузера.

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

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

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

Таблица 2.2. Некоторые важные переменные среды CGI Переменная среды Цель REMOTE_ADDR Адрес IP машины клиента. REMOTE_HOST Хост хозяина машины клиента. HTTP _ACCEPT Перечисляет типы MIME данных, которые браузер умеет интерпретировать. HTTP _USER_AGENT Информация браузера (тип браузера, номер версии, операционная система, и т.д.). REQUEST_METHOD GET или POST. CONTENT_LENGTH Размер ввода, если он послан через POST. Если не имеется никакого ввода или если используется метод GET, этот параметр не определен. QUERY_STRING Содержит вводимую информацию, когда она передается с помощью метода GET. PATH_INFO Позволяет пользователю определить путь от командной строки CGI (например, http://hostname/cgi-bin/programname/path). PATH_TRANSLATED Транслирует относительный путь в PATH_INFO в фактический путь в системе.

Чтобы записать приложение CGI, которое отображает переменные среды, нужно знать, как выполнить две вещи:

  • Определить все переменные среды и их соответствующие значения.
  • Вывести результаты для браузера.

Вы уже знаете, как выполнять последнюю операцию. В Perl переменные среды сохраняются в ассоциативном массиве %ENV, который вводится именем переменной среды. Листинг 2.3 содержит env.cgi, программу Perl, которая служит для достижения нашей цели.

Листинг 2.3. Программа Perl, env.cgi, которая выводит все переменные среды CGI.

#!/usr/local/bin/perl print "Content-type: text/html\n\n"; print " \n"; print "CGI Environment\n"; print "\n"; print "\n"; print "

CGI Environment

\n"; foreach $env_var (keys %ENV) { print "$env_var = $ENV{$env_var}
\n"; } print " \n";

Подобная программа может быть написана в C; полный код находится в Листинге 2.4.

Листинг 2.4. Env.cgi.c в C. /* env.cgi.c */ #include extern char **environ; int main() { char **p = environ; printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("CGI Environment\n"); printf("\n"); printf("\n"); printf("

CGI Environment

\n"); while(*p != NULL) printf("%s
\n",*p++); printf(" \n"); }

GET или POST ?

Какая разница между методами GET и POST? GET передает закодированную входную строку через переменную среды QUERY_STRING, а POST передает ее через stdin. POST - более предпочтительный метод, особенно для форм с большим количеством данных, потому-что здесь нет каких-либо ограничений в отношении объема посылаемой информации, а при методе GET объем пространства среды ограничен. GET имеет однако определенное полезное свойство; это подробно рассматривается в Главе 5 "Ввод".

Чтобы определить, который метод используется, программа CGI проверяет переменную среду REQUEST_METHOD, которая будет установлена либо в GET, либо в POST. Если она установлена в POST, длина закодированной информации сохранена в переменной среды CONTENT_LENGTH.

Закодированный Ввод

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

Чтобы определить это, браузер использует кодирующую спецификацию URL, которая может быть описана следующим образом:

  • Отделяет различные поля амперсандом (&).
  • Отделяет имя и значения знаками равенства (=), с именем слева и значением справа.
  • Заменяет пробелы знаками "плюс" (+).
  • Заменяет все "ненормальные" символы знаком процента (%), за которым следует двузначный шестнадцатеричный код символа.

Ваша конечная закодированная строка будет похожа на следующую:

Name1=value1&name2=value2&name3=value3 ...

Примечание: Спецификации для кодирования URL находятся в RFC1738.

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

Листинг 2.5. Код HTML для отображения формы имени и возраста.

Name and Age

Enter your name:

Enter your age:

Предположим, что пользователь вводит Joe Schmoe в поле имени, и 20 - в поле возраста. Ввод будет закодирован во входной строке.

Name=Joe+Schmoe&age=20

Синтаксический анализ ввода

Для того чтобы эта информация была полезной, нужно использовать информацию на что-то такое, что может быть использовано вашими программами CGI. Стратегии синтаксического анализа ввода рассматриваются в Главе 5. Практически, Вам никогда не придется думать о том, как анализировать ввод, потому что несколько специалистов уже написали доступные для всех библиотеки, которые производят синтаксический анализ. Две такие библиотеки представлены в настоящей главе в следующих разделах: cgi -lib.pl для Perl (написаны Стивом Бреннером) и cgihtml для C (написаны мной).

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

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

Cgi -lib.pl

Cgi -lib.pl использует ассоциативные массивы Perl. Функция &ReadParse анализирует входную строку и вводит каждую пару "имя / значение" по имени. Например, соответствующими строками Perl, необходимыми для декодирования только что представленной вводной строки "имя / возраст", были бы

&ReadParse(*input);

Теперь, чтобы увидеть значение, введенное для "имени", можно обращаться к ассоциативному массиву $input {"имя"}. Точно так же, чтобы обратиться к значению "возраста", нужно посмотреть на переменную $input {"возраст"}.

Cgihtml

C не имеет никаких встроенных структур данных, так что cgihtml осуществляет свой собственный список связей для использования со своими анализирующими подпрограммами CGI. Это определяет структуру entrytype следующим образом:

Typedef struct { Char *name; Char *value; } Entrytype;

Чтобы проанализировать вводную строку "name / age" ("имя / возраст") в C, используя cgihtml, используется следующее:

/* объявить связанный список, называемый вводом */ Llist input; /* анализировть ввод и место в связанном списке */ read_cgi_input(&input);

Чтобы обратиться к информации о возрасте, можно либо проанализировать список вручную, либо использовать имеющуюся функцию cgi _val ().

#include #include Char *age = malloc (sizeof (char) * strlen (cgi _val (input, "age")) + 1); Strcpy (age, cgi _val (input, "age"));

Значение "возраста" теперь сохранено в строке age.

Примечание: Вместо использования простого массива (подобно char age ;), я занимаюсь динамическим распределением пространства памяти для строки age. Хотя это усложняет программирование, тем не менее это важно с точки зрения безопасности. Более подробно о этом говорится в Главе 9.

Простая программа CGI

Вы собираетесь записать программу CGI, называемую nameage.cgi, которая обрабатывает форму "имя / возраст". Обработка данных (что я обычно называю "промежуточным материалом") минимальна. Nameage.cgi просто декодирует ввод и отображает имя пользователя и возраст. Хотя не особенно много пользы от такого инструмента, он демонстрирует наиболее критический аспект программирования CGI: ввод и вывод.

Вы используете ту же самую форму, как описано выше, вызывая поля "имя и возраст". Пока не стоит беспокоиться об ошибкоустойчивости и эффективности; решите имеющуюся задачу простейшим образом. Решения в Perl и C показаны соответственно в листингах 2.6 и 2.7.

Листинг 2.6. Nameage.cgi в Perl

#!/usr/local/bin/perl # nameage.cgi require "cgi-lib.pl" &ReadParse(*input); print "Content-Type: text/html\r\n\r\n"; print " \n"; print "Name and Age\n"; print "\n"; print "\n"; print "Hello, " . $input{"name"} . ". You are\n"; print $input{"age"} . " years old.

\n"; print " \n";

Листинг 2.7. nameage.cgi в C

/* nameage.cgi.c */ #include #include "cgi-lib.h" int main() { llist input; read_cgi_input(&input); printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("Name and Age\n"); printf("\n"); printf("\n"); printf("Hello, %s. You are\n",cgi_val(input,"name")); printf("%s years old.

\n",cgi_val(input,"age")); printf(" \n"); }

Обратите внимание на то, что эти две программы почти эквивалентны. Они обе содержат подпрограммы синтаксического анализа, которые занимают только одну строку и обрабатывают весь ввод (благодаря соответствующим библиотечным подпрограммам). Вывод, по существу, является измененной версией вашей основной программы Hello, World!.

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

Общая стратегия программирования

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

  • Простота
  • Эффективность
  • Универсальность

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

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

Резюме

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

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

Andover, Massachusetts, November 19, 2003

The Commerce Group, Inc. (NYSE: CGI), the largest writer of private passenger automobile insurance in Massachusetts and CGI Group Inc. (CGI) (TSX: GIB.A; NYSE: GIB;), a leading provider of information technology and business processing services, announced today the signing of a six-year business process outsourcing (BPO) contract renewal valued at US$35 million. CGI will provide full policy processing services for Massachusetts private passenger and commercial automobile lines as well as providing CGI"s CollaborativeEdge agency interface tool, application support and maintenance, regulatory support, systems consulting, and document management services.

Gerald Fels, Commerce Group"s executive vice-president and CFO, stated: "As the leading provider of private passenger automobile in Massachusetts, our goal is to provide our agents and employees with services that help them perform to their highest level. Over the years we have fostered a strong relationship with CGI. Their system is robust and accurate and their team is very familiar with our internal processing systems. That is important for us."

Serge LaPalme, president, insurance business services for CGI added: "We are very pleased to be continuing our relationship with the Commerce Group, one that spans over 30 years. The Commerce Group continues to be one of our valued business partners and is strategic to our success. In helping our client further focus on their core business, we are taking advantage of new technologies when and where it makes sense. Our team knows the insurance industry and the State"s very unique regulatory environment intimately and as a result are quick to adapt existing solutions to this constantly evolving sector."

About The Commerce Group, Inc.

The Commerce Group, Inc., an insurance holding company, is headquartered in Webster, Massachusetts. Commerce Group"s property and casualty insurance subsidiaries include The Commerce Insurance Company and Citation Insurance Company in Massachusetts, Commerce West Insurance Company in California and American Commerce Insurance Company in Ohio. Through its subsidiaries" combined insurance activities, Commerce Group is ranked as the 22nd largest personal automobile insurance group in the country by A.M. Best, based on 2002 direct written premium information.

About CGI
Founded in 1976, CGI is the fifth largest independent information technology services firm in North America, based on its headcount. CGI and its affiliated companies employ 20,000 professionals. CGI"s annualised revenue run-rate is currently CDN$2.8 billion (US$1.9 billion) and at September 30, 2003, CGI"s order backlog was CDN$12.3 billion (US$9.1 billion). CGI provides end-to-end IT and business process services clients worldwide from offices in Canada, United States and Europe. CGI"s shares are listed on the TSX (GIB.A) and the NYSE (GIB) and are included in the TSX 100 Composite Index as well as the S&P/TSX Canadian Information Technology and Canadian MidCap Indices. Website: .

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

E-commerce: что это такое?

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

Таким образом, это любая коммерческая сделка, которая совершается с помощью электронного средства связи.

Схема работы устроена следующим образом:

  • любой может быть блогер или любой другой обладатель собственной интернет-страницы) регистрируется в данной системе;
  • получает собственную ссылку;
  • размещает специальный код на своей веб-странице - появляется реклама выбранного официального партнера e-Commerce Partners Network;
  • следит за конверсией сайта;
  • зарабатывает определенный процент за каждую покупку посетителя своего сайта, перешедшего по партнерской ссылке.

WP e-Commerce

Большое количество людей сейчас увлечены электронной коммерций, в первую очередь по причине желания создать собственный веб-сайт, уникальный интернет-магазин для продажи собственной продукции. Для удовлетворения этого растущего спроса разработчики сконцентрировались на создании e-commerce template (шаблонов электронной коммерции). Что это такое рассмотрим далее.

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

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

Похожие статьи

© 2024 my-kross.ru. Кошки и собаки. Маленькие животные. Здоровье. Лекарство.