Використання
CGI при створенні інтерактивних інтерфейсів
4.1 WWW (World Wide Web) і засоби інтерактивної взаємодії p>
4.2Спеціфікація CGI
4.2.1Переменние оточення
4.2.2Стандартний висновок
4.2.3Стандартний вхідний потік
4.2.4Аргументи командного рядка p>
4.3Последовательность дій для обробки вхідних даних cgi-модуля для різних методів запиту GET та POST
4.3.1Для методу GET
4.3.2Для методу POST p>
4.4Прімери cgi-модулів p>
p>
4.1 WWW (World Wide Web) і засоби
інтерактивної взаємодії
Мета даної глави познайомити користувача з тією частиною WWW-технологій яка пов'язана зі створенням інтерактивних інтерфейсів і передбачається що
користувач знайомий з основами WWW, HTML і С/С + +. p>
У загальному випадку, інтерактивний інтерфейс користувача являє собою систему, що забезпечує взаємодію користувача і програми. Для WWW,
інтерактивний інтерфейс можна визначити як послідовність HTML-документів, що реалізують інтерфейс користувача. Можна також умовно
класифікувати принципи побудови інтерфейсу за типом формування HTML-документа: p>
статичний
динамічний
У першому випадку джерелом інтерфейсу є HTML-документ, створений в будь-якому текстовому або HTML-орієнтованому редакторі. Отже, даний
документ залишається незмінним протягом використання. У другому випадку джерелом інтерфейсу є HTML-документ згенерований cgi-модулем.
Отже, з'являється певна гнучкість у видозміні інтерфейсу під час використання. p>
Таким чином, можна ввести поняття інтерактивного інтерфейсу для WWW. p>
Інтерактивний інтерфейс для WWW є послідовність статичних або динамічно формованих HTML-документів, що реалізують інтерфейс
користувача. p>
Практично будь-яке завдання, що вирішує проблему отримання даних від клієнта, пов'язана з побудовою інтерфейсу. Найбільш цікавим є побудова
інтерфейсів до різних баз даних, доступ до SQL-сервера, отримання інформації від периферійних пристроїв, створення клієнтських робочих місць. Все це
можливо за допомогою CGI (Common Gateway Interface). p>
Common Gateway Interface (CGI) є стандартом інтерфейсу зовнішньої прикладної програми з WWW сервером. p>
Завдання побудови вищезгаданих інтерфейсів ділиться на дві частини: p>
Клієнтська частина
Серверна частина
p>
Малюнок 4-1. Дві частини інтерактивного інтерфейсу. h2>
Клієнтська частина
Для створення клієнтської частини необхідно створити HTML-документ, в якому реалізований інтерфейс з користувачем. У мові HTML це можливо за допомогою
форм. p>
Конструкції мови HTML, які використовуються при реалізації форм, дані в додатку
1 до гол. 4. p>
Серверна частина
Серверна частина складається з виконуваного модуля, що вирішує основні завдання обробки даних, що надходять від клієнтської частини, формування відповіді у форматі
HTML, і т.д. Такий модуль називається cgi-модулем b>. p>
Методи HTTP запиту
Для реалізації взаємодії "клієнт-сервер" важливо, який метод HTTP запиту використовує клієнтська частина при зверненні до WWW сервера. Загалом
випадку, запит - це повідомлення, що посилається клієнтом сервера. Перший рядок HTTP запиту (див. гл.3)
включає в себе метод, який повинен бути застосований до запитуваного ресурсу, ідентифікатор ресурсу (URI-Uniform Resource Identifier), і використовувану версію
HTTP-протоколу. У розглянутому нами випадку, клієнтська частина застосовує методи запиту POST b> і GET. b> Метод POST використовується для запиту
серверу, щоб той прийняв інформацію, включену в запит, як відноситься до ресурсу, вказаним ідентифікатором ресурсу. Метод GET використовується для
отримання будь-якої інформації, ідентифікованої ідентифікатором ресурсу в HTTP запиті. p>
Для WWW-сервера стандарту NCSA прикладні програми або CGI-модулі, які обробляють потік даних від клієнта або (і) формують зворотний потік
даних можуть бути написані на таких мовах програмування як: p>
C/C + +;
Будь-який UNIX shell;
Fortran;
Perl;
Visual Basic;
TCL;
AppleScript;
4.2 Специфікація CGI
CGI визначає 4 інформаційних потоку. p>
Змінні оточення
Стандартний вхідний потік
Стандартний вихідний потік
Командний рядок
p >
Малюнок 4-2. CGI-інтерфейс. h2>
4.2.1 Змінні оточення
Змінні оточення умовно поділяються на два типи: p>
загальні для всіх типів запитів (встановлюються для всіх типів)
залежать від методу запиту
До змінних першого типу відносяться наступні змінні: p>
SERVER_SOFTWARE b> містить інформацію про WWW сервер (назва/версія) p>
SERVER_NAME b> містить інформацію про ім'я машини, на якій запущений WWW сервер, символічне ім'я або IP адреса відповідні URL. p>
GATEWAY_INERFACE b> містить інформацію про версію CGI (CGI/версія) p>
Наступні змінні є специфічними для різних типів запитів і значення цим змінним присвоюються перед викликом cgi-модуля. p>
CONTENT_LENGTH b> значення цієї змінної відповідає довжині стандартного вхідного потоку в символах. p>
CONTENT_TYPE b> ця змінна специфікована для запитів містять додаткову інформацію, таких як HTTP POST і PUT, і містить тип даних
цієї інформації. p>
SERVER_PROTOCOL b> ця змінна містить інформацію про ім'я і версії інформаційного протоколу (протокол/версія). p>
SERVER_PORT b> значення змінної містить номер порту, на який був посланий запит. p>
REQUEST_METHOD b> метод запиту, що був використаний "POST", "GET", "HEAD" і т.д. p>
PATH_INFO b> значення змінної містить отриманий від клієнта віртуальний шлях до cgi-модуля p>
PATH_TRANSLATED b> значення змінної містить фізичний шлях до cgi-модуля, перетворений зі значення PATH_INFO. p>
SCRIPT_NAME b> віртуальний шлях до виконуваного модуля, який використовується для отримання URL. p>
QUERY_STRING b> значення цієї змінної відповідає рядку символів наступної за знаком "?" в URL відповідного даному запиту. Ця
інформація не декодується сервером. p>
REMOTE_HOST b> містить символічне ім'я віддаленої машини, з якої був зроблений запит. У разі відсутності даної інформації сервер привласнює
пусте значення і встановлює змінну REMOTE_ADDRESS. p>
REMOTE_ADDRESS b> містить IP адреса клієнта p>
AUTH_TYPE b> якщо WWW-сервер підтримує аутентифікацію (підтвердження автентичності) користувачів і cgi-модуль є захищеним від стороннього
доступу те, значення змінної специфікує метод аутотентіфікаціі. p>
REMOTE_USER b> містить ім'я користувача у випадку аутотентіфікаціі. p>
REMOTE_IDENT b> містить ім'я користувача, отримане від сервера (якщо сервер підтримує аутентифікацію згідно RFC 931) p>
HTTP_ACCEPT b> список типів MIME відомих клієнтові. Кожен тип у списку повинен бути відокремлений комою згідно специфікації HTTP (тип/підтип, тип/підтип і
т.д.) p>
HTTP_USER_AGENT b> назва програми перегляду яку використовує клієнт при посилці запиту. p>
4.2.2 Стандартний вивід
СGI b> - модуль виводить інформацію у стандартний вихідний потік. Цей висновок може являти собою або документ, згенерований cgi-модулем, або
інструкцію серверу, де отримати необхідний документ. Зазвичай cgi b>-модуль робить свій висновок. Перевага такого підходу в тому, що cgi b>-модуль
не повинен формувати повний HTTP заголовок на кожен запит. p>
Заголовок вихідного потоку b>
У деяких випадках необхідно уникати обробки сервером виведення cgi-модуля, і
надсилати клієнту дані без змін. Для відмінності таких cgi-модулів, CGI вимагає, щоб їх імена починалися на nph-. У цьому випадку формування
синтаксично правильної відповіді клієнту cgi-модуль бере на себе. p>
Заголовки з синтаксичним розбором b>
Висновок cgi-модуля повинен починатися із заголовка містить певні рядка
і завершуватися двома символами CR (0x10). p>
Будь-які рядки не є директивами сервера, посилаються безпосередньо клієнтові. На даний момент, CGI специфікація визначає три директиви сервера: p>
Content-type b>
MIME або тип повертається документа p>
Наприклад: Content-type b>: text/html повідомляє серверу, що наступні за цим повідомленням дані - є документ у форматі HTML
p>
Location b>
вказує серверу, що повертається не сам документ, а посилання на нього p>
Якщо аргументом є URL, то сервер передасть клієнтові вказівку на перенаправлення запиту. Якщо аргумент є віртуальний шлях,
сервер поверне клієнтові заданий цим шляхом документ, як якби клієнт запитував цей документ безпосередньо. p>
Наприклад: Location: b> http://host/file.txt призведе до того, що WWW сервер видасть file.txt, як якби він був затребуваний клієнтом. Якщо cgi-модуль
повертає посилання на gopher сервер, наприклад на gopher:// gopher.ncsa.uiuc.edu /. Висновок буде наступний: p>
Location b>: gopher:// gopher.ncsa.uiuc.edu/ p>
* Status b>
задає серверу HTTP/1.0 рядок-статус, яка буде послана клієнтові у форматі:
nnn xxxxx p>
де: nnn - 3-х цифровий код статусу p>
ххххх - рядок причини p>
Наприклад: HTTP/1.0 200 OK b> p>
Server: NCSA/1.0a6 p>
Content-type: text/plain p>
p>
У даному випадку, клієнтові буде повідомлено про успішне виконання запиту. p>
4.2.3 Стандартний вхідний потік
У випадку методу запиту POST b> дані передаються як вміст HTTP запиту. І будуть надіслані в стандартний вхідний потік. p>
Дані передаються cgi-модуля в наступній формі: p>
name = value & name1 = value1 &...& nameN = valueN
де name - ім'я змінної,
value - значення змінної,
N - кількість змінних p>
На файловий дескриптор стандартного потоку введення посилається 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, а у стандартний потік введення посилається блок даних. p>
У випадку методу GET b>, рядок даних передається як частина URL.
Тобто наприклад
http://host/cgi-bin/script?name1=value1&name2=value2 p>
У цьому випадку змінна оточення QUERY_STRING приймає значення
name1 = value1 & name2 = value2 p>
4.2.4 Аргументи командного рядка
СGI b>-модуль у командному рядку від сервера отримує: p>
залишок URL після імені cgi-модуля як перший параметр
(перший параметр буде порожній, якщо було присутнє тільки ім'я cgi-модуля), і
список ключових слів як залишок командного рядка для
скрипта пошуку, або
чергуються імена полів форми з доданим знаком рівності та
відповідних значень змінних.
Ключові слова, імена та значення полів форми передаються декодувати (з HTTP URL формату кодування) і перекодованими відповідно до правил
кодування Bourne shell так, що cgi-модуль у командному рядку отримає інформацію без необхідності здійснювати додаткові перетворення. p>
4.3 Послідовність дій для
обробки вхідних даних cgi-модуля для різних методів запиту GET та POST
Виходячи з різниці методів запитів GET і POST, можна визначити послідовність дій для обробки вхідних даних cgi-модуля для різних
типів запитів. p>
4.3.1 Для методу GET
Отримати значення змінної QUERY_STRING
Декодувати імена та їх значення (враховуючи, що всі пробіли при
декодуванні сервером були замінені символом "+" і всі символи
з десятковим кодом більше 128 перетворені у символ "%" і
наступним за ним шістнадцятковим кодом символу.)
Сформувати структуру відповідності "ім'я - значення" для
подальшого використання в cgi-модуль
4.3.2 Для методу POST
Отримати зі стандартного вхідного потоку CONTENT_LENGTH символів
Декодувати імена та їх значення (враховуючи, що всі пробіли при
декодуванні сервером були замінені символом " + b>" і все
символи з десятковим кодом більше 128 перетворені у символ "% b>"
і наступним за ним шістнадцятковим кодом символу.)
Сформувати структуру відповідності "ім'я - значення" для
подальшого використання в cgi-модуль
Очевидно, що відмінність тільки в джерелі даних. Тому, в принципі, можливе створення єдиного модуля для методів POST і GET. Необхідно тільки
додати почало перевірку значення змінної REQUEST_METHOD для визначення методу запиту. Після формування структури "ім'я-значення" можна
приступити до вирішення завдань, заради яких, власне, створювався cgi-модуль. Зрозуміло, що завдання, які вирішуються cgi-модулем, можуть бути дуже різноманітними
(отримання і обробка пошти, доступ до баз даних, гостьова книга і т.д.). p>
Наступним важливим моментом є динамічне формування cgi-модулем HTML-документа (оформлення результату роботи модуля). Наприклад, таблиці вибірки
з бази даних. p>
Для цього cgi-модуль повинен видати в стандартний вихідний потік заголовок складається з рядка:
Content-type: text/html b> і порожнього рядка (двох символів CR b>) p>
Після цього заголовка можна давати будь-який текст у форматі HTML. p>
4.4 Приклади cgi-модулів
Як приклад розглянемо роботу тестових програм поставляються разом з програмним забезпеченням сервера НТТРD стандарту NCSA. p>
Для тестування роботи форм поставляються програми:
post-query b> - для тестування роботи форм з методом запиту POST
query b> - для тестування роботи форм з методом запиту GET
util.c - b> опис функцій для обробки вхідного потоку (використовується
query і post-query). p>
Розглянемо простий приклад форми на мові HTML використовує програму query. p>
Приклад використання CGI
Введіть своє ім'я (Прізвище Ім'я По-батькові): b>
Стать: - чоловічий-жіночий
p>
Після ініціації форми шляхом натискання кнопки "Відправити запит" WWW сервер обробляє потік даних від форми (замінює всі пробіли в іменах і
значеннях на символ "+", замінює всі символи з десятковим кодом великим 128 на символ "%" і наступним за ним шістнадцятковим кодом
символу (наприклад "І" у% С8)).
Вихідний потік прийме наступний вигляд: p>
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 p>
У момент передачі управління модулю post-query сервер присвоює значення змінних оточення і аргументам командного рядка: p>
argc = 0. argv =
SERVER_SOFTWARE = NCSA/1.5.1
SERVER_NAME = iceman.cnit.nsu.ru
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = POST
HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg ,*/*< br> 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 p>
Результат роботи post-query:
Query ResultsYou submitted the following name/value
pairs:
RealName = Петров Іван Сидорович
Sex = Мужской
Submit = Надіслати запит
p>
І на екрані браузера
Query Results
You submitted the following name/value pairs:
RealName = Петров Іван Сидорович
Sex = Мужской
Submit = Надіслати запит p>
Нижче приведений початковий текст програми post-query. p>
# 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] = '? да POST і програмою query. Для цього змінимо
значення атрибутів ACTION і METHOD в тезі FORM. p>
p>
Після ініціації форми сервер встановить наступні значення для змінних оточення і аргументів командного рядка: p>
argc = 0. argv is =
SERVER_SOFTWARE = NCSA/1.5.1
SERVER_NAME = iceman.cnit.nsu.ru
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = 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 = p>
Як ми бачимо, вихідний потік від форми з'явився в значенні змінної QUERY_STRING. p>
Результат роботи query повністю збігається з результатом роботи post-query. p>
Додаток 1 до гл.4 Конструкції мови HTML
для побудови форм
... b> p>
використання: призначений для отримання інформації від клієнта і визначає початок і кінець форми. p>
атрибути: p>
Обов'язкові
ACTION b> - визначає URI (Universal Resource Identifier-адреса або
місце розташування документа) CGI-скрипта
METHOD b> - визначає метод передачі інформації скрипту. Можливі
значення GET або POST.
Необов'язкові
[ENCTYPE] b> - визначає тип MIME декодування інформації (значення цього
атрибуту за замовчуванням - "application/x-www-form-urlencoded").
[SCRIPT] b> - використовується для передачі URI скрипта. Мова скрипта і
інтерфейс користувача при цьому не є частиною специфікації HTML 3.0
Важливо: b> Форми не можуть бути вкладеними! p>
Для реалізації форми використовуються наступні теги. p>
b> p>
використання: призначений для створення різних за своєю функціональністю полів вводу. p>
атрибути: p>
Обов'язкові:
TYPE b> - визначає тип поля форми. p>
Допустимі значення:
TEXT b> - дозволяє символьний введення.
PASSWORD b> - призначене для "прихованого" вводу символів
(Зауважте, що ви не відображаються).
CHECKBOX b> - поле, що дозволяє два стани ( "є",
"ні"). Повинен застосовуватися з атрибутами NAME і VALUE
RADIO b> - поле, що дозволяє вибір "один з усіх"
SUBMIT b> - кнопка ініціює передачу інформації з форми
обробному скрипту, визначеному в ACTION відповідно до методу,
певним атрибутом METHOD.
RESET b> - кнопка, що скидаються всі введені раніше значення.
IMAGE b> - поле дозволяє відтворити подія SUBMIT за допомогою
вашого зображення, при цьому повертається два значення: name.x =
координата Х та name.y = координата Y, де Х і Y координати положення
курсор миші на зображенні в момент клацання.
HIDDEN b> - поле створює неотображаемое значення.
RANGE b> - визначає поле дозволяє ввести цифрове значення з
певними допустимими верхнім і нижнім межами.
Використовується разом з атрибутами MAX і MIN визначальними область
допустимих значень (наприклад: TYPE = RANGE MIN = 1 MAX = 10).
NAME b> - значення цього атрибута визначає ідентифікатор поля.
VALUE b> - значення цього атрибута визначає що буде передано як значення за умовчанням для даного поля при ініціації форми.
SRC b> - визначає URI файлу зображення. Використовується тільки з типом поля IMAGE.
[CHECKED] b> - дозволяє встановити початкове значення поля типу CHECKBOX.
SIZE b> - визначає розмір поля.
[MAXLENGTH] b> - визначає максимальну кількість символів, допустима для введення в поле.
[ALIGN] b> - дозволяє позиціонування p>
Допустимі значення:
по вертикалі
TOP b> - вирівнювання по верху.
MIDDLE b> - вирівнювання по середині.
BOTTOM b> вирівнювання по низу.
Ці значення використовуються тільки з TYPE = IMAGE.
по горизонталі
[LEFT] b> - вирівнювання ліворуч
[RIGHT] b> - вирівнювання праворуч
[DISABLED] b> - визначає поле як "read only" - тільки для
читання. Значення у полі не може бути змінено користувачем.
[ERROR] b> - визначає повідомлення про помилку, що пояснює, чому введене
значення в полі не вірно. p>
... b> p>
використання: призначений для визначення області введення тексту. Розмір поля визначається атрибутами. p>
атрибути: p>
NAME b> - значення цього атрибута визначає ідентифікатор поля. Повертається при ініціації форми.
ROWS b> - визначає кількість рядків у текстовій області.
COLS b> - визначає кількість стовпців в текстовій області.
[VALUE] b> - задає значення за замовчуванням.
[DISABLED] b> - визначає поле як "read only" - тільки для
читання. Значення у полі не може бути змінено користувачем.
[ERROR] b> - визначає повідомлення про помилку, що пояснює, чому введене
значення в полі не вірно. p>
b>
b> значення1
... b>
b> значеніеN
b> p>
використання: призначений для визначення області вибору з декількох значень (меню). p>
Атрибути: p>
NAME b> - значення цього атрибута визначає ідентифікатор поля. Повертається при ініціації форми.
[SIZE] b> - визначає кількість видимих можливих значень.
[MULTIPLE] b> - визначає можливість множинного вибору.
[DISABLED] b> - визначає меню як "read only" - тільки для читання. Значення в меню не може бути вибрано користувачем і показується
сірим кольором. p>
b> значення p>
використання: використовується тільки для визначення з пунктів меню. p>
атрибути: p>
SELECTED b> - визначає значення за замовчуванням
VALUE b> - визначає повертається значення p>
Примітка: в [] дані необов'язкові атрибути p>