CGI на С шаг за шагом (часть первая) - Programming <!--%IFTH1%0%-->- Articles<!--%IFEN1%0%--> - Каталог статей - V . S . I . S ( Volgograd site on information safety )
Суббота, 31.07.2010, 16:49
Приветствую Вас USER | RSS
Главная
Регистрация
Вход
Меню сайта

Категории каталога
breaking and research of programs [10]
Programming [37]
Cryptography and enciphering [2]
Breaking and protection [2]
Networks and reports [0]
Windows vs Unix [1]
About the Internet programs [0]
the Miscellaneous [0]
Lessons on programming [0]
freaking [1]
carding [1]
to beginners [10]

Мини-чат
200

Наш опрос
Я юзаю:
Всего ответов: 24

Главная » Статьи » Articles » Programming [ Добавить статью ]

CGI на С шаг за шагом (часть первая)

Шаг 1 - Что такое CGI ?

CGI - Common Gateway Interface является стандартом интерфейса, который служит для связи внешней программы с веб-сервером. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, многие больше любят названия скрипт или CGI-программа.

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

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

В web-сервере Apache такая настройка производится с помощью файла .htaccess в той директории, где содержится этот скрипт. Вот содержание такого файла:

 Options ExecCGI

Также Apache позволяет запускать все скрипты имеющие рассширение .cgi, если в файле настроек сервера httpd.conf есть настройка:

 AddHandler cgi-script .cgi

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


Шаг 2 - Передача данных шлюзу.

Передача данных шлюзу осуществляется в следующем формате:

имя=значение&имя1=значение1&... 

Здесь "имя" это название параметра, а "значение" его содержимое. Методов передачи данных в таком формате существует два - GET и POST. При использовании метода GET данные передаются серверу вместе с URL:

http://.../cgi-bin/test.cgi?имя=значение&имя1=значение1&...

При использовании метода POST данные посылаются внутри самого HTTP запроса.

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

Получение данных самим скриптом также различается. При использовании метода GET данные следующие за "?" помещаются в переменную среды QUERY_STRING. При использовании POST содержимое запроса перенаправляется в стандартный поток ввода, т.е. в stdin.

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

В имена и значения параметров при передаче кодируются браузером URL методом, т.е. все символы не принадлежащие к латинскому алфавиту и числам кодируются в виде %HH, где HH - шестнадцатеричное значение кода символа. Также кодируются все символы , которые нельзя использовать, т.е. !#%^&()=+ и пробел. Символ "&" используется, как мы уже видели для разделения пар "имя=значение", "" используется в парах "имя=значение", "%" для кодирования символов, "пробел" кодируется символом "+"(плюс), сам же плюс кодируется через "%", и т.д. Поэтому при анализе полученных данных требуется их переводить в нормальных вид.

Пример кодировки символов и букв при передаче:

Передается строка: !@#$%^&*()-=_+ абвгд
Скрипт получает : %21@%23%24%25%5E%26*%28%29-%3D_%2B+%E0%E1%E2%E3%E4

Размер передаваемых данных методом POST содержится в переменной окружения CONTENT_LENGTH:

Передается : a=4&b=1
CONTENT_LENGTH = 7



Шаг 3 - Структура CGI программы.

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

Как получать данные ?

Весь процесс получения данных от веб-сервера можно представить следуюшим образом:

  1. Получить все необходимые переменные окружения. Наиболее важной на данном этапе является REQUEST_METHOD.
  2. Получить данные от сервера в зависимости от метода передачи:
     Если (REQUEST_METHOD="GET") то
     Взять данные из переменной окружения QUERY_STRING
     Иначе
     Если (REQUEST_METHOD="POST") то
     Проанализировать переменную QUERY_STRING
     Получить длинну данных из CONTENT_LENGTH
     Если (CONTENT_LENGTH>0) то
     Считать CONTENT_LENGTH байт из sdtin как данные.
     Иначе
     Выдать сообщение об ошибке и выйти.
    
  3. Декодировать все полученные данные и, если надо, разбить их на пары "имя=значение" в удобную для программы форму.

С анализом переменной REQUEST_METHOD думаю все ясно, а вот ,что значит в методе POST проанализировать QUERY_STRING, наверно, не все ясно. При передаче методом POST сервер посылает данные через стандартный поток ввода, но это не значит, что пользователь не пользовался URL'ом для передачи данных. Примером может служить многопользовательский шлюз, в котором для идентификации пользователя используется URL, а для передачи данных stdin:

 http://.../cgi-bin/guestbook.cgi?user=bob&rec=0

В этом случае шлюзу гостевой книги (guestbook.cgi) сообщается два параметра user и rec, с помощью которых она может узнать "куда записывать" или "как обрабатывать" данные поступающие через поток ввода.

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

Пример:

 char cgi_data[1000];
 ...
 long content_length=atol(getenv("CONTENT_LENGTH"));
 fread(cgi_data,content_length,1,stdin);
 ...

Надеюсь все сразу видно :-)). Если content_length>1000, то произойдет переполнение cgi_data. Переполнение буферов это излюбленный метод атаки хакеров. Вместо этого лучше выделять память динамически:

 char *cgi_data;
 ...
 long content_length=atol(getenv("CONTENT_LENGTH"));
 cgi_data=(char *)malloc(content_length);
 if (cgi_data!=NULL)
 fread(cgi_data,content_length,1,stdin);
 ...

После получения данных от сервера их надо еще декодировать. Можно это сделать сразу, а можно по мере надобности. Если Вы будете это делать сразу, то Вам также придется их разбить на куски, так как при декодировании могут появиться лишние знаки "&" и "=", которые больше не позволят вам отделять пары "имя=значение" друг от друга.

Вот пример процедуры, которая декодирует данные из буфера:

/* Возвращает верхний регистр символа*/
char upperchar(char ch)
{
 if ((ch>='a') && (ch<='z'))
 {
 ch='A'+(ch - 'a');
 return ch;
 }
 else return ch;
};

/* Переводит из Hex в Dec*/
char gethex(char ch)
{
 ch=upperchar(ch);
 if ((ch>='0')&&(ch<= '9')) return (ch-'0');
 if ((ch>='A')&&( ch<='F')) return (ch-'A'+10);
};

/* 
 Ищет и возвращает параметр с именем name, в buffer.
 Если параметр name не найден, возвращает NULL.
 
Пример : message = getparam(post_buffer,"message=");

Замечание : символ "=" после имени параметра не удаляется
 и входит в возвращаемый результат, поэтому рекомендуется
 искать параметр вместе с символом "=".
 */
 
char *getparam(char *buffer,char *name)
{
 if (buffer==NULL) return NULL;

 char *pos;
 long leng=512,i=0,j=0;
 char h1,h2,Hex;

 char *p=(char *)malloc(leng);
 pos=strstr(buffer,name);
 if (pos == NULL) return NULL;

 if ((pos!=buffer) && (*(pos-1)!='&')) return NULL; 

 pos+=strlen(name);
 
 while ( (*(pos+i)!='&')&&( *(pos+i)!='�' ))
 {
 if ( *(pos+i)=='%' )
 {
 i++;
 h1=gethex(*(pos+i));
 i++;
 h2=gethex(*(pos+i));
 h1=h1<<4;
 *(p+j)=h1+h2;
 }
 else
 {
 if (*(pos+i)!='+') *(p+j)=*(pos+i);
 else *(p+j)=' ';
 };
 i++;
 j++;
 if (j >= leng) p=(char*)realloc(p,leng+20);
 leng+=20;
 };
 if (j < leng) p=(char*)realloc(p,j+1);
 
 *(p+j)='�';
 return p;
};

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

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

Шаг 4 - Обработка данных шлюзом.

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

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

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

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

Пример реализации данного метода:

 FILE f_lock;

/* ..... */

 int counter;
 /* Проверяем наличие временного файла */
 while ((f_lock = fopen("lock.$", "r")) != NULL)
 {
 fclose(f_lock);
 counter++;
 if (counter>15000)
 {
 /*Сообщаем об ошибке и выходим */
 printf("Error !!! Can't delete lock.$ file.");
 return 1;
 };
 };

 /* Создаем временный файл */
 f_lock = fopen("lock.$", "w");
 fclose(f_lock);

 /*... Работа основной части скрипта ...*/

 /* Удаляем временный файл */
 while (remove("lock.$")!=0);

Как видно этот способ достаточно прост в реализации и точно убережет Вас от неправильной работы скрипта.

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

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

Шаг 5 - Вывод информации.

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

Существуют два типа заголовков, вернее даже три, но один из них используется реже (о нем мы поговорим отдельно). Так вот, первый заголовок осуществляет переадресацию браузера на другой ресурс в сети и записывается вот как:

Location: URL-адрес ресурса

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

Пример:

Location: http://www.mjk.msk.ru/~dron/88.gif

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

Content-type: тип данных

Тип данных создается из двух составляющих: его типа и формата. То есть, сначала указывается один из следующих типов:

  • application - данные для какого-либо приложения
  • audio - аудио данные, например RealAudio
  • video - видео данные, например MPEG или AVI
  • image - изображение
  • text - текст

Далее через /(слэш) указывается формат данных.

Примеры заголовков:

Content-type: text/html
Content-type: image/gif
Content-type: video/mpeg

Еще заголовок может включать в себя вспомогательные параметры, Content-length - длина содержимого, Expires - время существования в кэше и т.д.

Каждый параметр указывается в отдельной строке и заканчивается переносом строки n.

Пример:

Content-type: image/gif
Content-length: 1052

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

 ...
 printf("Content-type: text/htmln");
 printf("n");
 printf("<html><h1>Simple CGI for example !!!</h1></html>");
 ...

Если отделяющая пустая строка (я ее сделал отдельной строкой в коде) не будет отправлена, то сервер выдаст ошибку 500 Internal Server Error : Bad header.

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

Шаг 6 - Переменные среды о сервере.

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

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

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

GATEWAY_INTERFACE
Указывает версию интерфейса CGI, который поддерживает сервер. Например:
CGI/1.1
SERVER_NAME
Содержит IP адрес сервера или его доменное имя. Например:
www.mjk.msk.ru
SERVER_PORT
Номер порта, по которому сервер получает http запросы. Стандартный порт для этого 80.
SERVER_PROTOCOL
Версия протокола Http, который использует сервер для обработки запросов. Например:
 HTTP/1.1
SERVER_SOFTWARE
Название и версия программы сервера. Например:
Apache/1.3.3 (Unix) (Red Hat/Linux)

Эти переменные обеспечивают все необходимые данные о сервере, на котором запускается скрипт. Если Ваш сервер сконфигурирован для работы с одним хостом, то скорее информация эта вам не понадобится. Сейчас же большинство серверов позволяют создавать так называемые "виртуальные" хосты. Т.е. это один компьютер, который поддерживает много IP адресов и различает запросы от клиентов по требуемому хосту, на которые он соответственно выдает странички с сайтов. Тут уже могут понадобиться данные о портах сервера (т.к. многие хосты просто "сидят" на других портах, например 8080, 8081 и т.д.) и его IP адрес с именем.

Шаг 7 - Переменные среды о запросе.

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

AUTH_TYPE
Тип авторизации используемой сервером. Например:
Basic

Подробнее об авторизации в сервере Apache читайте в "Шаг 18 - Авторизация посетителей".

CONTENT_FILE
Путь к файлу с полученными данными. Используется только в серверах под Windows. Например:
c:websitecgi-temp103421.dat
CONTENT_LENGTH
Длинна переданной информации в байтах. То бишь сколько надо считать байтов из stdin. Например:
10353
CONTENT_TYPE
Тип содержимого посланного серверу клиентом. Например:
text/html
OUTPUT_FILE
Файл для вывода данных, используется только серверами под Windows. Аналогично CONTENT_FILE.
PATH_INFO и PATH_TRANSLATED
В современных веб-серверах появилась возможность после имени скрипта указывать еще какой-то определенный путь. Для чего он нужен скрипту я пока не очень понимаю. Но видимо некоторым он сможет пригодиться. Эти переменные работают следующим образом. Предположим существует скрипт с именем 1.cgi в каталоге сервера /cgi-bin, тогда при вызове скрипта в таком виде:
 http://.../cgi-bin/1.cgi/dir1/dir2
данные переменные установятся следующим образом:
PATH_INFO=/dir1/dir2
PATH_TRANSLATED=/home/httpd/html/dir1/dir2

Помоему видно, что эти переменные будут указывать на папку относительно корневой директории сервера. При этом PATH_TRANSLATED будет содержать абсолютный путь до этого каталога на диске сервера. В данном случае корневым каталогом сервера считается /home/httpd/html/, и еще замечу, что это путь в Unix системах.

Под dos/win системами переменная PATH_INFO не изменится, а PATH_TRANSLATED будет содержать d:apachehtdocsdir1dir2 (в данном случае корнем сервера является директория d:apachehtdocs).

QUERY_STRING
Содержит данные переданные через URL. Такие данные указываются после имени шлюза и знака ?. Пример:
http://.../cgi-bin/1.cgi?d=123&name=kostia
тогда переменная QUERY_STRING будет содержать
 d=123&name=kostia
и еще незабывайте, что данные передаваемые таким образом кодируются методом URL.
REMOTE_ADDR
Содержит IP адрес пользователя пославшего запрос шлюзу. Если Вы обращаетесь к любому шлюзу в интернете, то данная переменная будет содержать ваш IP адрес. Пример:
 192.168.1.36
REMOTE_HOST
Содержит ваше доменное имя, при условии, что вы прописаны на каком-либо DNS сервере. Например, если ваш Dial-UP провайдер регистрирует все свои динамические IP адреса на DNS сервере, то при обращении к шлюзу, эта переменная может содержать примерно следующее:
d6032.dialup.cornell.edu
или
dial57127.mtu-net.ru
или
ppp-130-66.dialup.metrocom.ru
(брал прямо из логов сервера :-)
REQUEST_METHOD
Мы раньше говорили об этой переменной. Она содержит метод передачи данных шлюзу: GET или POST.
REQUEST_LINE
Содержит строку из запроса протокола HTTP. Например:
GET /cgi-bin/1.cgi HTTP/1.0
SCRIPT_NAME
Содержит имя вызванного скрипта. Например: 1.cgi.

Все эти переменные, надеюсь, обеспечат Вам все самые необходимые данные о запросе к шлюзу.

Шаг 8 - Переменные среды о клиенте.

Осталось рассмотреть еще несколько переменных, которые несут в себе информацию о клиенте пославшем запрос.

Их не много, всего три:

HTTP_ACCEPT
Эта переменная пречисляет все типы данных, которые может получать и обрабатывать клиент. Часто содержит просто */*, т.е. клиент может получать все подряд. Пример:
 */*,image/gif,image/x-xbitmap 
HTTP_REFERER
Содержит URL страницы, с которой был произведен запрос, т.е. которая содержит ссылку на шлюз. Пример:
 http://www.firststeps.ru/index.html
HTTP_USER_AGENT
Содержит в себе название и версию браузера, которым пользуется клиент для запроса. Полезно для того, чтобы игнорировать браузеры ненавистных вам фирм :-))). Пример:
MyBrowser/1.0 (MSIE 4.0 Compatible, Win98)

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

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

HTTP_ACCEPT_ENCODING
Указывает набор кодировок, которые может получать клиент. Например:
koi8-r, gzip, deflate
HTTP_ACCEPT_LANGUAGE
Содержит в себе список языков в кодах ISO, которые может принимать клиент. Например:
ru, en, fr
HTTP_IF_MODIFIED_SINCE
Содержит в себе дату, новее которой должны быть получаемые данные.
HTTP_FROM
Содержит список почтовых адресов клиента.

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

Шаг 9 - Обработка простой формы.

Понятие формы языка html описано в "Шаг 19 - Изящные формы" раздела Html&Web. Давайте сделаем простую форму.

<form action="http://localhost/cgi-bin/primer.cgi" method=GET>
Введите свое имя пользователя:
<input type=text maxlength=150 name=user>
<p><input type=submit value=Send>
</form>

Мы уже обсуждали методы передачи данных в шлюз раньше. Какие тут могут быть советы ? Лично мне кажется передавать такие маленькие формы лучше всего посредством метода GET. С чем это связано ? Во-первых получить данные из переменной окружения намного легче, чем считать их из потока. Чтобы считать данные из потока надо точно знать их размер, позаботиться о выделении памяти и многом другом. Тут же обо всем позаботится сервер и встроенные средства программирования вашего языка. Во-вторых пользователь сможет обратиться к вашему скрипту непосредственно из адресной строки браузера. Например, многие программы для поиска информации в интернете используют различные поисковые сервера. Для того чтобы сделать запрос к одному из них требуется всего лишь вызвать браузер и сообщить ему URL. В Windows это делается просто в командной строке (а значит и просто сделать программе):

 start http://www.abc.com/cgi-bin/search.cgi?word=hello&language=ru

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

С методом POST в этом отношении сложнее, для этого программе нужно уметь работать по протоколу HTTP и связываться с серверами в интернете. Размер и сложность такой программы будет на порядок выше. Поэтому, если Ваш ресурс может быть полезен и при этом передаваемые ему данные не будут превышать 32 Кб (это ограничение на длинну URL, если я все правильно помню :-), то лучше метода GET не найти.

Давайте напишем программу для обработки этой формы.

#include <stdio.h>
#include <stdlib.h>

//Здесь надо вставить процедуру получения
//параметра по его имени... Она была описана
//раньше.

char *getparam(...)
{
};

int main()
{
 char *user=NULL;
 char *content=NULL;
 char *request_method=getenv("REQUEST_METHOD");
 if (strcmp(request_method,"GET")!=0)
 {
 printf("Content-type: text/htmlnn");
 printf("Unknown REQUEST_METHOD. Use only GET !n");
 return -1;
 };
 
 content=getenv("QUERY_STRING");
 user=getparam(content,"user=");
 printf("Content-type: text/htmlnn");
 printf("User name="%s"n",user);
};

После того как вся программа будет собрана и откомпилированна, расположите ее в директории cgi-bin вашего вебсервера. Теперь можно смело пробовать форму написанную выше. Я для теста использовал браузер напрямую... Как я уже говорил, достаточно набрать

 http://localhost/cgi-bin/primer.cgi?user=hello
И Вы увидите тот же результат, что и при использовании формы. Кстати вот он:
 User name="hello" 

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

Категория: Programming | Добавил: ^KeRnEl^ (06.08.2008)
Просмотров: 221 | Рейтинг: 0.0/0 |
Всего комментариев: 0

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
E-mail:
Пароль:

Поиск

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0


V . S . I . S ( Volgograd Site on Information Safety ) © 2010
Хостинг от uCoz