Структура CGl-программы.

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

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

Все скрипты, как правило, помещают в каталог cgi (или cgi-bin) сервера, но это необязательно: скрипт может располагаться где угодно, но при этом большинство веб-серверов требуют специальной настройки. В веб-сервере Apache, например, такая настройка может производиться при помощи общего файла настроек httpd.conf или с помощью файла .htaccess в том каталоге, где содержится этот скрипт.

CGI является одним из наиболее распространённых средств создания динамических веб-страниц.

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

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

1. Получить все необходимые переменные окружения. Наиболее важной на данном этапе является REQUEST_METHOD.

2. Получить данные от сервера в зависимости от метода передачи:

3. Если (REQUEST_METHOD="GET") то

4. Взять данные из переменной окружения QUERY_STRING

5. Иначе

6. Если (REQUEST_METHOD="POST") то

7. Проанализировать переменную QUERY_STRING

8. Получить длинну данных из CONTENT_LENGTH

9. Если (CONTENT_LENGTH>0) то

10. Считать CONTENT_LENGTH байт из sdtin как данные.

11. Иначе

12. Выдать сообщение об ошибке и выйти.

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

С анализом переменной 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)!='\0' ))

{

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)='\0';

return p;

};

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


 








Дата добавления: 2016-04-23; просмотров: 936;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.019 сек.