4.1 WWW (World Wide Web) і засоби інтерактивної взаємодії
4.2Спеціфікація CGI
4.2.1Переменние оточення
4.2.2Стандартний висновок
4.2.3Стандартний вхідний потік
4.2.4Аргументи командного рядка
4.3Последовательность дій для обробки вхідних даних cgi-модуля для різних методів запиту GET і POST
4.3.1Для методу GET
4.3.2Для методу POST
4.4Прімери cgi-модулів
4.1 WWW (World Wide Web) і засоби інтерактивної взаємодіїМета даної глави познайомити користувача з тією частиною WWW-технологій яка пов'язана зі створенням інтерактивних інтерфейсів і передбачається що користувач знайомий з основами WWW, HTML і С / С + +.
У загальному випадку, інтерактивний інтерфейс користувача являє собою систему, що забезпечує взаємодію користувача і програми. Для WWW, інтерактивний інтерфейс можна визначити як послідовність HTML-документів, що реалізують інтерфейс користувача. Можна також умовно класифікувати принципи побудови інтерфейсу за типом формування HTML-документа:
статичний динамічнийУ першому випадку джерелом інтерфейсу є HTML-документ, створений в будь-якому текстовому або HTML-орієнтованому редакторі. Отже, даний документ залишається незмінним протягом використання. У другому випадку джерелом інтерфейсу є HTML-документ згенерований cgi-модулем. Отже, з'являється деяка гнучкість у видозміні інтерфейсу під час використання.
Таким чином, можна ввести поняття інтерактивного інтерфейсу для WWW.
Інтерактивний інтерфейс для WWW являє собою послідовність статичних або динамічно сформованих HTML-документів, що реалізують інтерфейс користувача.
Практично будь-яке завдання, що вирішує проблему отримання даних від клієнта, пов'язана з побудовою інтерфейсу. Найбільш цікавим є побудова інтерфейсів до різних баз даних, доступ до SQL-сервера, отримання інформації від периферійних пристроїв, створення клієнтських робочих місць. Все це можливо за допомогою CGI (Common Gateway Interface).
Common Gateway Interface (CGI) є стандартом інтерфейсу зовнішньої прикладної програми з WWW сервером.
Завдання побудови вищезгаданих інтерфейсів ділиться на дві частини:
Клієнтська частина Серверна частинаМалюнок 4-1. Дві частини інтерактивного інтерфейсу.
Клієнтська частинаДля створення клієнтської частини необхідно створити HTML-документ, в якому реалізований інтерфейс з користувачем. У мові HTML це можливо за допомогою форм.
Конструкції мови HTML, які використовуються при реалізації форм, дані в додатку 1 до гол. 4.
Серверна частинаСерверна частина складається з виконуваного модуля, що вирішує основні завдання обробки даних, що надходять від клієнтської частини, формування відповіді у форматі HTML, і т.д. Такий модуль називається cgi-модулем.
Методи HTTP запитуДля реалізації взаємодії "клієнт-сервер" важливо, який метод HTTP запиту використовує клієнтська частина при зверненні до WWW сервера. У загальному випадку, запит - це повідомлення, що посилається клієнтом серверу. Перший рядок HTTP запиту (див. гл.3) включає в себе метод, який повинен бути застосований до запитуваного ресурсу, ідентифікатор ресурсу (URI-Uniform Resource Identifier), і використовувану версію HTTP-протоколу. У розглянутому нами випадку, клієнтська частина застосовує методи запиту POST і GET. Метод POST використовується для запиту серверу, щоб той прийняв інформацію, включену в запит, як і ставиться до ресурсу, зазначеному ідентифікатором ресурсу. Метод GET використовується для отримання будь-якої інформації, ідентифікованої ідентифікатором ресурсу в HTTP запиті.
Для WWW-сервера стандарту NCSA прикладні програми або CGI-модулі, які обробляють потік даних від клієнта або (і) формують зворотний потік даних можуть бути написані на таких мовах програмування як:
C / C + +; Будь UNIX shell; Fortran; Perl; Visual Basic; TCL; AppleScript; 4.2 Специфікація CGICGI визначає 4 інформаційних потоку.
Змінні оточення Стандартний вхідний потік Стандартний вихідний потік Командний рядокМалюнок 4-2. CGI-інтерфейс.
4.2.1 Змінні оточенняЗмінні оточення умовно діляться на два типи:
загальні для всіх типів запитів (встановлюються для всіх типів) залежать від методу запитуДо змінних першого типу належать такі змінні:
SERVER_SOFTWARE містить інформацію про WWW сервері (назва / версія)
SERVER_NAME містить інформацію про ім'я машини, на якій запущений WWW сервер, символічне ім'я або IP адресу відповідні URL.
GATEWAY_INERFACE містить інформацію про версії CGI (CGI / версія)
Наступні змінні є специфічними для різних типів запитів і значення цим змінним присвоюються перед викликом cgi-модуля.
CONTENT_LENGTH значення цієї змінної відповідає довжині стандартного вхідного потоку в символах.
CONTENT_TYPE ця змінна специфікована для запитів містять додаткову інформацію, таких як HTTP POST і PUT, і містить тип даних цієї інформації.
SERVER_PROOL ця змінна містить інформацію про ім'я і версії інформаційного протоколу (протокол / версія).
SERVER_PORT значення змінної містить номер порту, на який був посланий запит.
REQUEST_METHOD метод запиту, який був використаний "POST", "GET", "HEAD" і т.д.
PATH_INFO значення змінної містить отриманий від клієнта віртуальний шлях до cgi-модуля
PATH_TRANSLATED значення змінної містить фізичний шлях до cgi-модуля, перетворений з значення PATH_INFO.
SCRIPT_NAME віртуальний шлях до виконуваного модуля, який використовується для отримання URL.
QUERY_STRING значення цієї змінної відповідає рядку символів наступної за знаком "?" в URL відповідного даному запиту. Ця інформація не декодується сервером.
REMOTE_HOST містить символічне ім'я віддаленої машини, з якої був зроблений запит. У разі відсутності даної інформації сервер привласнює пусте значення і встановлює змінну REMOTE_ADDRESS.
REMOTE_ADDRESS містить IP адреса клієнта
AUTH_TYPE якщо WWW-сервер підтримує аутентифікацію (підтвердження дійсності) користувачів і cgi-модуль є захищеним від стороннього доступу те, значення змінної специфікує метод аутотентіфікаціі.
REMOTE_USER містить ім'я користувача у разі аутотентіфікаціі.
REMOTE_IDENT містить ім'я користувача, отримане від сервера (якщо сервер підтримує аутентифікацію згідно RFC 931)
HTTP_ACCEPT список типів MIME відомих клієнтові. Кожен тип у списку має бути відділений комою згідно специфікації HTTP (тип / підтип, тип / підтип і т.д.)
HTTP_USER_AGENT назва програми перегляду яку використовує клієнт при посилці запиту.
4.2.2 Стандартний вивідСGI - модуль виводить інформацію у стандартний вихідний потік. Цей висновок може бути або документ, згенерований cgi-модулем, або інструкцію сервера, де отримати необхідний документ. Зазвичай cgi-модуль проводить свій висновок. Перевага такого підходу в тому, що cgi-модуль не повинен формувати повний HTTP заголовок на кожен запит.
Заголовок вихідного потоку
У деяких випадках необхідно уникати обробки сервером виведення cgi-модуля, і посилати клієнту дані без змін. Для відмінності таких cgi-модулів, CGI вимагає, щоб їх імена починалися на nph-. У цьому випадку формування синтаксично правильної відповіді клієнту cgi-модуль бере на себе.
Заголовки з синтаксичним розбором
Висновок cgi-модуля повинен починатися з заголовка містить певні рядки і завершуватися двома символами CR (0x10).
Будь-які рядки не є директивами сервера, посилаються безпосередньо клієнтові. На даний момент, CGI специфікація визначає три директиви сервера:
Content-type
MIME або тип повертається документа
Наприклад: Content-type: text / html повідомляє серверу, що наступні за цим повідомленням дані - є документ у форматі HTML
Location
вказує серверу, що повертається не сам документ, а посилання на нього
Якщо аргументом є URL, то сервер передасть вказівку клієнту на перенаправлення запиту. Якщо аргумент являє собою віртуальний шлях, сервер поверне клієнтові заданий цим шляхом документ, як якби клієнт запитував цей документ безпосередньо.
Наприклад: Location: http://host/file.txt призведе до того, що WWW сервер видасть file.txt, як якщо б він був затребуваний клієнтом. Якщо cgi-модуль повертає посилання на gopher сервер, наприклад на gopher: / / gopher.ncsa.uiuc.edu /. Висновок буде наступний:
Location: gopher: / / gopher.ncsa.uiuc.edu /
* Status
задає серверу HTTP/1.0 рядок-статус, яка буде надіслана клієнта у форматі: nnn xxxxx
де: nnn - 3-х цифровий код статусу
ххххх - рядок причини
Наприклад: HTTP/1.0 200 OK
Server: NCSA/1.0a6
Content-type: text / plain
У даному випадку, клієнту буде повідомлено про успішне виконання запиту.
4.2.3 Стандартний вхідний потікУ випадку методу запиту POST дані передаються як вміст HTTP запиту. І будуть надіслані в стандартний вхідний потік.
Дані передаються cgi-модуля в такій формі:
name = value & name1 = value1 &...& nameN = valueN
де name - ім'я змінної,
value - значення змінної,
N - кількість змінних
На файловий дескриптор стандартного потоку введення посилається CONTENT_LENGTH байт. Так само сервер передає cgi-модулем CONTENT_TYPE (тип даних). Сервер не посилає символ кінця файлу після передачі CONTENT_LENGTH байт даних або після того, як cgi-модуль їх прочитає. Змінні оточення CONTENT_LENGTH і CONTENT_TYPE встановлюються в той момент, коли сервер виконує cgi-модуль. Таким чином, якщо в результаті виконання форми з аргументом тега FORM - METHOD = "POST" сформований рядок даних firm = МММ & price = 100023, то сервер встановить значення CONTENT_LENGTH рівним 21 і CONTENT_TYPE в application / x-www-form-urlencoded, а в стандартний потік введення посилається блок даних.
У випадку методу GET, рядок даних передається як частина URL.
Тобто наприклад
http://host/cgi-bin/script?name1=value1&name2=value2
У цьому випадку змінна оточення QUERY_STRING приймає значення
name1 = value1 & name2 = value2
СGI-модуль у командному рядку від сервера отримує:
залишок URL після імені cgi-модуля як перший параметр (перший параметр буде порожній, якщо було присутнє тільки ім'я cgi-модуля), і список ключових слів як залишок командного рядка для скрипта пошуку, або чергуються імена полів форми з доданим знаком рівності та відповідних значень змінних.Ключові слова, імена і значення полів форми передаються декодувати (з HTTP URL формату кодування) і перекодованими відповідно до правил кодування Bourne shell так, що cgi-модуль у командному рядку отримає інформацію без необхідності здійснювати додаткові перетворення.
4.3 Послідовність дій для обробки вхідних даних cgi-модуля для різних методів запиту GET і POSTВиходячи з різниці методів запитів GET і POST, можна визначити послідовність дій для обробки вхідних даних cgi-модуля для різних типів запитів.
4.3.1 Для методу GET Отримати значення змінної QUERY_STRING Декодувати імена та їх значення (з огляду, що всі пробіли при декодуванні сервером були замінені символом "+" і всі символи з десятковим кодом більше 128 перетворені на символ "%" і наступним за ним шістнадцятковим кодом символу.) Сформувати структуру відповідності "ім'я - значення" для подальшого використання в cgi-модулі 4.3.2 Для методу POST Отримати зі стандартного вхідного потоку CONTENT_LENGTH символів Декодувати імена та їх значення (з огляду, що всі пробіли при декодуванні сервером були замінені символом "+ "і всі символи з десятковим кодом більше 128 перетворені на символ"% "і наступним за ним шістнадцятковим кодом символу.) Сформувати структуру відповідності" ім'я - значення "для подальшого використання в cgi-модуліОчевидно, що відмінність тільки в джерелі даних. Тому, в принципі, можливе створення єдиного модуля для методів POST і GET. Необхідно тільки додати в початок перевірку значення змінної REQUEST_METHOD для визначення методу запиту. Після формування структури "ім'я-значення" можна приступити до вирішення завдань, заради яких, власне, створювався cgi-модуль. Зрозуміло, що завдання, які вирішуються cgi-модулем, можуть бути дуже різноманітними (отримання і обробка пошти, доступ до баз даних, гостьова книга і т.д.).
Наступним важливим моментом є динамічне формування cgi-модулем HTML-документа (оформлення результату роботи модуля). Наприклад, таблиці вибірки з бази даних.
Для цього cgi-модуль повинен видати в стандартний вихідний потік заголовок складається з рядка:
Content-type: text / html і порожнього рядка (двох символів CR)
Після цього заголовка можна давати будь-який текст у форматі HTML.
4.4 Приклади cgi-модулівЯк приклад розглянемо роботу тестових програм поставляються разом з програмним забезпеченням сервера НТТРD стандарту NCSA.
Для тестування роботи форм поставляються програми:
post-query - для тестування роботи форм з методом запиту POST
query - для тестування роботи форм з методом запиту GET
util.c - опис функцій для обробки вхідного потоку (використовується query і post-query).
Розглянемо простий приклад форми на мові HTML використовує програму query.
Приклад використання CGI
Введіть своє ім'я (Прізвище Ім'я По-батькові):
Стать: - чоловічий-жіночий
Після ініціації форми шляхом натискання кнопки "Відправити запит" WWW сервер обробляє потік даних від форми (замінює всі прогалини в іменах і значеннях на символ "+", заміняє всі символи з десятковим кодом великим 128 на символ "%" і наступним за ним шістнадцятковим кодом символу (наприклад "І" у% С8)).
Вихідний потік прийме наступний вигляд:
RealName =% CF% E5% F2% F0% EE% E2 +% C8% E2% E0% ED +% D1% E8% E4% EE% F0
% EE% E2% E8% F7 & Sex =% CC% F3% E6% F1% EA% EE% E9 & Submit =% CF% EE% F1
% EB% E0% F2% FC +% E7% E0% EF% F0% EE% F1
У момент передачі управління модулю post-query сервер привласнює значення змінних оточення і аргументам командного рядка:
argc = 0. argv =
SERVER_SOFTWARE = NCSA/1.5.1
SERVER_NAME = iceman.cnit.nsu.ru
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = POST
HTTP_ACCEPT = image / gif, image / x-xbitmap, image / jpeg, image / pjpeg, * / *
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = / cgi-bin/test-cgi
QUERY_STRING =
REMOTE_HOST = fwa.cnit.nsu.ru
REMOTE_ADDR = 193.124.209.74
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE = application / x-www-form-urlencoded
CONTENT_LENGTH = 142
Результат роботи post-query:
Query ResultsYou submitted the following name / value pairs:
RealName = Петров Іван Сидорович
Sex = Чоловічий
Submit = Надіслати запит
І на екрані браузера
Query Results
You submitted the following name / value pairs:
RealName = Петров Іван Сидорович
Sex = Чоловічий
Submit = Надіслати запит
Нижче приведений вихідний текст програми post-query.
# Include
# Ifndef NO_STDLIB_H
# Include
# Elsechar * getenv ();
# Endif
# Define MAX_ENTRIES 10000
typedef struct {
char * name;
char * val;
} Entry;
char * makeword (char * line, char stop);
char * fmakeword (FILE * f, char stop, int * len);
char x2c (char * what);
void unescape_url (char * url);
void plustospace (char * str);
main (int argc, char * argv [])
{
entry entries [MAX_ENTRIES];
register int x, m = 0;
int cl;
printf ("Content-type: text / html% c% c", 10,10);
if (strcmp (getenv ("REQUEST_METHOD"), "POST"))
{Printf ("This script should be referenced with a METHOD of POST.n");
printf ("If you don't understand this, see this"); printf ("forms overview.% c", 10);
exit (1);
} If (strcmp (getenv ("CONTENT_TYPE"), "application / x-www-form-urlencoded"))
{Printf ("This script can only be used to decode form results. N");
exit (1);
}
cl = atoi (getenv ("CONTENT_LENGTH"));
for (x = 0; cl & & (! feof (stdin)); x + +)
{M = x; entries [x]. Val = fmakeword (stdin ,'&',& cl); plustospace (entries [x]. Val);
unescape_url (entries [x]. val);
entries [x]. name = makeword (entries [x]. val ,'=');
}
printf ("Query Results");
printf ("You submitted the following name / value pairs:% c", 10);
printf ("% c", 10);
for (x = 0; x br tt / * Призначена для виділення рядка, обмеженого "стоп-символом" Bstop, / B з потоку Bf / B довжиною Bcl. / B / ttbr tt * / / tt br ttint wsize; / tt br ttchar * word; / tt br ttint ll; / ttbr br ttwsize = 102400; / tt br ttll = 0; / tt br ttword = (char *) malloc (sizeof (char) * (wsize + 1)); / ttbr br ttwhile (1) {/ tt br ttword [ll] = (char) fgetc (f); / tt br ttif (ll == wsize) {/ tt br ttword [ll +1] = ''; / tt br ttwsize + = 102400; / tt br ttword = (char *) realloc (word, sizeof (char) * (wsize +1)); / tt br tt} / tt br tt - (* cl); / tt br ttif ((word [ll] == stop) | | (feof (f)) | | (! (* cl))) {/ tt br ttif (word [ll]! = stop) ll + +; / tt br ttword [ll] = ' '; / tt br ttreturn word; / tt br tt} / tt br tt + + ll; / tt br tt} / tt br tt} / ttbr br br ttchar Bx2c / B (char * what) {/ tt br tt / * Призначена для перетворення шестнадцатірічное коду символу в код символу / ttbr tt * / / tt br ttregister char digit; / ttbr br ttdigit = (what [0]> = 'A'? ((what [0] & 0xdf) - 'A ') +10: (what [0] - "0"));
digit *= 16;
digit + = (what [1]> = 'A'? ((what [1] & 0xdf) - 'A') +10: (what [1] - "0"));
return (digit);
}
void unescape_url (char * url) {
register int x, y;
for (x = 0, y = 0; url [y]; + + x, + + y) {
if ((url [x] = url [y]) == '%') {
url [x] = x2c (& url [y +1]);
y + = 2;
}
}
url [x] = '';
}
void plustospace (char * str) {
/ * Заміна символів "+" на символ "пробіл" * /
register int x;
for (x = 0; str [x]; x + +) if (str [x] == '+') str [x] = '';
}
Для демонстрації реалізації форми з методом запиту GET скористаємося тієї ж самою формою, що і для методу POST і програмою query. Для цього змінимо значення атрибутів ACTION і METHOD в тезі FORM.
Після ініціації форми сервер встановить наступні значення для змінних оточення та аргументів командного рядка:
argc = 0. argv is =
SERVER_SOFTWARE = NCSA/1.5.1
SERVER_NAME = iceman.cnit.nsu.ru
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = image / gif, image / x-xbitmap, image / jpeg, image / pjpeg, * / *
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = / cgi-bin/test-cgi
QUERY_STRING = RealName =% CF% E5% F2% F0% EE% E2 +% C8% E2% E0% ED +% D1% E8
% E4% EE% F0% EE% E2% E8% F7 & Sex =% CC% F3% E6% F1% EA% EE% E9 & Submit =% CF% EE% F1% EB% E0% F2% FC +% E7% E0% EF % F0% EE% F1
REMOTE_HOST = fwa.cnit.nsu.ru
REMOTE_ADDR = 193.124.209.74
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =
Як ми бачимо, вихідний потік від форми з'явився в значенні змінної QUERY_STRING.
Результат роботи query повністю збігається з результатом роботи post-query.
Додаток 1 до гл.4 Конструкції мови HTML для побудови форм...
використання: призначений для отримання інформації від клієнта і визначає початок і кінець форми.
атрибути:
Обов'язковіACTION - визначає URI (Universal Resource Identifier-адреса або місце розташування документа) CGI-скрипта
METHOD - визначає метод передачі інформації скрипту. Можливі значення GET або POST. Необов'язкові
[ENCTYPE] - визначає тип MIME декодування інформації (значення цього атрибуту за замовчуванням - "application / x-www-form-urlencoded").
[SCRIPT] - використовується для передачі URI скрипта. Мова скрипта і інтерфейс користувача при цьому не є частиною специфікації HTML 3.0
Важливо: Форми не можуть бути вкладеними!
Для реалізації форми використовуються наступні теги.
використання: призначений для створення різних за своєю функціональністю полів введення.
атрибути:
Обов'язкові:TYPE - визначає тип поля форми.
Допустимі значення:TEXT - дозволяє символьний введення.
PASSWORD - призначено для "прихованого" введення символів (що вводяться символи не відображаються).
CHECKBOX - поле, що дозволяє два стани ("є", "ні"). Повинен застосовуватися з атрибутами NAME і VALUE
RADIO - поле, що дозволяє вибір "один з усіх"
SUBMIT - кнопка ініціює передачу інформації з форми обробляє скрипту, визначеному в ACTION відповідно до методу, певним атрибутом METHOD.
RESET - кнопка, скидає всі введені раніше значення.
IMAGE - поле дозволяє відтворити подія SUBMIT за допомогою вашого зображення, при цьому повертається два значення: name.x = координата Х і name.y = координата Y, де Х і Y координати положення курсору миші на зображенні в момент клацання.
HIDDEN - поле створює неотображаемое значення.
RANGE - визначає поле дозволяє ввести цифрове значення з певними допустимими верхнім і нижнім межами.
Використовується разом з атрибутами MAX і MIN визначальними область допустимих значень (наприклад: TYPE = RANGE MIN = 1 MAX = 10).
NAME - значення цього атрибута визначає ідентифікатор поля.
VALUE - значення цього атрибута визначає що буде передано як значення за замовчуванням для даного поля при ініціації форми.
SRC - визначає URI файлу зображення. Використовується тільки з типом поля IMAGE.
[CHECKED] - дозволяє встановити початкове значення поля типу CHECKBOX.
SIZE - визначає розмір поля.
[MAXLENGTH] - визначає максимальну кількість символів, допустима для введення в полі.
[ALIGN] - дозволяє позиціонування
TOP - вирівнювання по верху.
MIDDLE - вирівнювання по середині.
BOTTOM вирівнювання по низу.
Ці значення використовуються тільки з TYPE = IMAGE. по горизонталі
[LEFT] - вирівнювання зліва
[RIGHT] - вирівнювання праворуч
[DISABLED] - визначає поле як "read only" - тільки для читання. Значення у полі не може бути змінено користувачем.
[ERROR] - визначає повідомлення про помилку, що пояснює, чому введене значення в полі не вірно.
...
використання: призначений для визначення області введення тексту. Розмір поля визначається атрибутами.
атрибути:
NAME - значення цього атрибута визначає ідентифікатор поля. Повертається при ініціації форми.
ROWS - визначає кількість рядків в текстовій області.
COLS - визначає кількість стовпців в текстовій області.
[VALUE] - задає значення за замовчуванням.
[DISABLED] - визначає поле як "read only" - тільки для читання. Значення у полі не може бути змінено користувачем.
[ERROR] - визначає повідомлення про помилку, що пояснює, чому введене значення в полі не вірно.
значення1
...
значеніеN
використання: призначений для визначення області вибору з кількох значень (меню).
Атрибути:
NAME - значення цього атрибута визначає ідентифікатор поля. Повертається при ініціації форми.
[SIZE] - визначає кількість видимих можливих значень.
[MULTIPLE] - визначає можливість множинного вибору.
[DISABLED] - визначає меню як "read only" - тільки для читання. Значення в меню не може бути вибрано користувачем і показується сірим кольором.
значення
використання: використовується тільки с для визначення пунктів меню.
атрибути:
SELECTED - визначає значення за замовчуванням
VALUE - визначає значення, що повертається
Примітка: у [] дано необов'язкові атрибути