После того, как вы
установили CGI, имеются несколько способов
выполнить его. Если ваш CGI -программа, работающая
только с выводом, типа программы Hello,World!, тогда Вы
может выполнять ее, просто обращаясь к ее URL.
Большинство программ выполняется как серверное
приложение к форме HTML. Прежде, чем научиться, как
получать информацию от этих форм, сначала
прочтите краткое введение о создании таких форм.
Два наиболее важных тега в форме HTML - это теги
для обозначения конца формы. Нельзя иметь форму внутри формы, хотя Вы можете установить форму, которая позволяет представлять части информации в различные местах; этот аспект широко рассматривается в Главе 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, как в процессе обучения, так и для
отладки. В таблице 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 "
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("
printf("
printf("\n");
printf("\n");
printf("
CGI Environment
\n");While(*p != NULL)
printf("%s
\n",*p++);
Printf(" \n");
}
Какая разница между методами 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 ...
Например, предположим, что у вас была форма, которая запросила имя и возраст. Код HTML, который использовался для отображения этой формы, представлен в листинге 2.5.
Листинг 2.5. Код HTML
для отображения формы имени и возраста.
Предположим, что
пользователь вводит 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.
В Главе 5 глубже
рассматриваются эти и другие библиотеки. На
данный момент, Вы готовы применить свои знания о
вводе и выводе для того, чтобы записать
полноценную, и в то же время простую, программу 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 "
print "
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("
printf("
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. Вы создаете вывод, правильно
форматируя ваши данные и печатая в stdout. Получение
ввода CGI является несколько более сложным делом,
потому что он должен быть проанализирован до
своего использования. К счастью, уже существуют
несколько библиотек, которые осуществляют
синтаксический анализ.
К данному моменту Вы должны достаточно легко
справиться с программированием приложений CGI.
Оставшаяся часть настоящей книги посвящена
более подробному изложению спецификации,
подсказкам и стратегии программирования более
продвинутых и сложных приложений.
Бесплатный движок форума на Perl, первая версия которого вышла в самом конце XX века, 4 июля 2000 года. Да-да, XXI век, вопреки распространенному заблуждению, начался лишь с 1 января 2001 года.
На машине времени мы перенесемся в 2000 год и посмотрим, как все начиналось.
→ Демо-версия самого первого YaBB (логин: admin, пароль: admin).
Немного истории
Некий Zef Hemel в начале 2000 года хотел создать свой форум и искал подходящий движок. Лучшим из того, что он нашел, были платные UBB (Ultimate Bulletin Board) за $200 и vBulletin, а также бесплатные UltraBoard 1.62 и PowerBoard. Однако эти форумы табличные, а Zef хотел древовидный в стиле «Usenet» с блекджеком и смайликами.В итоге Zef Hemel выбрал бесплатный UltraBoard и некоторое время его использовал. Однако со временем ему стало не хватать его возможностей, но он не смог найти форум с необходимым ему функционалом. Zef принимает решение создать свой движок форума.
Поскольку Zef Hemel изначально хотел иметь древовидный форум, он начал модифицировать уже существующий движок RobBoard. Работая над форумом, к нему пришло прозрение: древовидные форумы теряют популярность и морально устарели, поскольку нажимать на каждое сообщение, чтобы прочитать его - это очень неудобно. Таким образом, он отказался от идеи создать древовидный форум и переписал его в табличный, каким он и остается до сих пор.
Изначально он хотел сделать движок платным, но затем изменил свою позицию. Он решил сделать бесплатный форум с открытым исходным кодом для таких же бедных вебмастеров, как он сам. Первая версия форумного движка была выпущена 4 июля 2000 года, в День независимости США. Свой движок он назвал YaBB - Yet another Bulletin Board. В переводе с английского это означает «Еще одна Доска Объявлений».
Вскоре к проекту присоединились еще несколько программистов: Andy Tomaka (специалист по UBB), Remake (специалист по UltraBoard), Matt Mecham (создатель Ikonboard, позже стал руководителем Invision Power Services). Zef опубликовал свой скрипт в различных каталогах CGI-программ, в том числе в CGI-Resource Index.
Новый движок набирал популярность, его начали использовать сайты с высокой посещаемостью. Форум постоянно модернизировался, за несколько лет был выпущен целый ряд новых версий - YaBB 1 Final, YaBB 1 Gold и т.д. Zef Hemel со временем покинул проект, его эстафету приняли новые энтузиасты. Было выпущено огромное количество разнообразных модификаций, собранных на сайте BoardMod .
На смену пришел YaBB 2. Первая публичная версия в статусе Release Candidate вышла 27 декабря 2004 года. Его основные нововведения - возможность прикреплять файлы к сообщениям и создавать опросы.
Последняя версия из этой ветки, 2.6.11, была выпущена 17 декабря 2014 года. Ведется разработка YaBB 3.
На основе YaBB был создан аналогичный движок на PHP, использующий СУБД MySQL, получивший название YaBB SE . В свою очередь, он стал основой популярного ныне движка SMF (Simple Machines Forum) .
YaBB Original Release
Итак, устанавливаем самую первую версию YaBB. Стоит уточнить, что нижеприведенная инструкция справедлива для серверов, работающих на базе операционных систем типа Linux и FreeBSD.Инсталлятор отсутствует, поэтому установка производится простым копированием файлов в папку cgi-bin (в текстовом режиме) и в папку для HTML-файлов (в бинарном режиме). Для файлов YaBB.pl , Printpage.pl , Search.pl , Reminder.pl устанавливаются соответствующие права доступа, позволяющие их выполнение (обычно 755). Учетная запись администратора уже создана (логин: admin, пароль: admin).
Однако начиная со 2-й половины 2000-х гг. YaBB начал терять свои позиции. Среди основных факторов, повлиявших на это, можно назвать распространение бесплатных движков, работающих на PHP и MySQL, а также хостингов с поддержкой этих технологий. Многие владельцы форумов перешли с YaBB на другие движки (как правило, на SMF).
Тем не менее, в отличие от других аналогичных движков (UBB, Ikonboard, UltraBoard и т.д.), YaBB не прекратил разработку, а продолжил выпускать новые версии, которые также написаны на Perl и хранят данные в текстовых файлах, но при этом по функциональности не уступают популярным бесплатным форумам на PHP и MySQL.
Теги:
- yabb
- форум
1) Общие сведения о CGI
С 1993 года CGI является очень часто используемой технологией создания трехзвенных клиент/серверных приложений в Интернет. CGI-приложение совместно с Web-сервером выполняют роль сервера приложений в трехзвенной архитектура клиент/сервер. CGI – набор правил (спецификация), согласно которым пользовательские программы, запускаемые на Web-сервера, могут возвращать данные клиенту в виду HTML-документа. CGI – это консольное приложение, загружаемое в ответ на запрос клиента на выборку или обновление данных, функционирующее как отдельный однопоточный процесс под управлением Web-сервера и выгружаемое сразу после завершения работы. WinCGI – Windows реализация CGI.
2) Варианты реализации
Программа, запускаемая Web-сервером в соответствии со спецификацией CGI, называется CGI-скриптом. Она может быть написана на любом языке программирование (С, Basic, Pascal и т.п.) или на командной языке (языки shell, perl и т.п.), допускающем создание исполняемых модулей. CGI-скрипт исполняет роль посредника между Web-сервером и другими серверами, например, сервером БД, и поэтому часто называется шлюзом. CGI-программы по умолчанию размещаются в каталоге C:\InetPub\Scripts|Cgi-bin, но можно создавать и свой виртуальный каталог.
3) Способы взаимодействия CGI и WEB-сервера
В спецификации CGI предусмотрено несколько способов взаимодействия CGI-программы и Web-сервера, отличающиеся вариантом обмена данными между сервером и программой.
. Передача параметров в командной строке (например, с помощью дескриптором ISINDEX, помещаемого в раздел
. Передача значений переменных окружения (их более 17 штук).
. Передача данных через стандартный входной поток (STDIN, STDOUT).
Запрос типа ISINDEX – это запрос вида: http://site.ru/somthig-cgi/cgi-script?слово1+слово2+слово3
Главным здесь является список слов после символа «?». Слова перечисляются через символ «+» и для кириллицы не кодируются в шестнадцатеричные последовательности. Последовательность слов после символа «?» будет размещена в переменной окружения QUERY_STRING.
Запрос типа FORM-URLENCODED – это запрос вида: http://site.ru/something-cgi/cgi-script?field=word1&field2=word2
Данные формы записываются в виде пар «имя_поля-значение», которые разделены символом «&».
Переменные окружения, которые не зависят от типа запроса:
SERVER_SOFTWARE
– показывает название и версию http-сервера в формате: название/версия.
SERVER_NAME
– показывает доменное имя сервера.
SERVER_ADDR
– показывает IP сервера.
SERVER_ADMIN
– e-mail администратора web-сервера.
GATEWAY_INTERFACE
– версия CGI на момент компиляции httpd демона в формате: CGI/версия
DATE_GMT
– текущая дата и время во временной зоне GMT.
DATE_LOCAL
– текущие дата и врем во временной зоне сервера.
DOCUMENT_ROOT
– путь к главному каталогу web-сервера.
Переменные окружения, которые зависят от типа запроса:
SERVER_PROTOCOL
– протокол, по которому был получен запрос.
SERVER_PORT
– порт, на который был получен запрос.
REQUEST_METHOD
– тип запроса: POST, GET и так далее.
REQUEST_URL
– страница, отправившая запрос.
SCRIPT_NAME
– URL скрипта без имени сервера.
SCRIPT_FILENAME – полное имя файла скрипта на диске.
QUERY_STRING
– информация, содержащаяся в командной строке вызова скрипта (после? в URL’е).
CONTENT_TYPE
– MIME-тип данных, передаваемых скрипту.
CONTENE_LENGTH
– длина передаваемых данных.
Поток стандартного вывода:
Ввод данных в скрипт через поток стандартного ввода осуществляется только при использовании метода доступа к ресурсу (к скрипту) POST. При этом в переменную окружения CONTENT_LENGTH помещается число символов, которое необходимо считать из потока стандартного ввода скрипта, а в переменную окружения CONTENT_TYPE помещается тип кодирования данных, которые считывают из потока стандартного ввода. При посимвольном считывании в С можно применить, например, такой фрагмент кода:
int n;
char *buf;
n=atoi(getenv(*CONTENT_LENGTH*));
buf=(char *)malloc(n+1);
memset(buf, ‘\000’,n+1);
for (i=0; iBR> {buf[i]=getchar()}
…
free(buf);
4) Методы передачи данных
a) Метод GET выполняет передачу данных CGI-программе через переменные окружения (среды), которые фактически добавляются к URL через разделительный знак?.
Прежде всего, для этих целей используется переменная query_string – длинная строка, состоящая из пар имя = значение, отделяемых друг от друга символом амперсанда — &. Получается быстро, однако объем передаваемых данных не превышает 256?1024 байт в зависимости от типа Web-сервера.
b) Метод POST выполняет передачу данных через стандартный поток ввода stdin (Ini-файл для WinCGI). Фактически данные добавляются к телу HTML-запроса. Количество передаваемых байт указывается в переменной среды content_length. Это более медленный способ передачи данных, но объем передаваемых данных не ограничен.
c) Параметр HREF тэга A
Помимо методов GET и POST тэга