Пример CGI-сценария
Настало время привести небольшой сценарий на Си, который иллюстрирует некоторые возможности, которые были описаны выше (листинг 3.1).
Листинг 3.1. Простейший сценарий script.c
#include <time.h> // Íóæíà äëÿ èíèöèàëèçàöèè ôóíêöèè rand()
#include <stdio.h> // Âêëþ÷àåì ïîääåðæêó ôóíêöèé ââîäà/âûâîäà
#include <stdlib.h> // À ýòî— äëÿ ïîääåðæêè ôóíêöèè rand()
// Ãëàâíàÿ ôóíêöèÿ. Èìåííî îíà è çàïóñêàåòñÿ ïðè ñòàðòå ñöåíàðèÿ.
void main(void) {
// èíèöèàëèçèðóåì ãåíåðàòîð ñëó÷àéíûõ ÷èñåë
int Num; time_t t; srand(time(&t));
// â Num çàïèñûâàåòñÿ ñëó÷àéíîå ÷èñëî îò 0 äî 9
Num = rand()%10;
// äàëåå âûâîäèì çàãîëîâêè îòâåòà. Òèï — html-äîêóìåíò
printf("Content-type: text/html\n");
// çàïðåò êýøèðîâàíèÿ
printf("Pragma: no-cache\n");
// ïóñòîé çàãîëîâîê
printf("\n");
// âûâîäèì òåêñò äîêóìåíòà — åãî ìû óâèäèì â áðàóçåðå
printf("<html><body>");
printf("<h1>Çäðàâñòâóéòå!</h1>");
printf("Ñëó÷àéíîå ÷èñëî â äèàïàçîíå 0-9: %d",Num);
printf("</body></html>");
}
Исходный текст можно откомпилировать и поместить в каталог с CGI- сценариями на сервере. Обычно стараются все сценарии хранить в одном месте — в каталоге cgi-bin, у которого имеется разрешение на выполнение всех файлов внутри него. Правда, это правило не является обязательным — конечно же, можно разместить файлы сценария где душе угодно (не забыв проставить соответствующие права на каталог в настройках сервера). На мой взгляд, логично хранить файлы сценариев там, где это наиболее вам удобно, а не пользоваться общепринятыми штампами. Теперь наберем в адресной строке браузера:
http://www.myhost.com/cgi-bin/script.cgi
Мы получим нашу HTML-страницу. Заметьте, что при нажатии Reload
(а также при повторном посещении страницы) браузер перезагрузит страницу целиком, а не возьмет ее копию из своего кэша (это можно видеть по постоянно изменяющемуся случайному числу или по лампочкам модема). Мы добились такого результата благодаря заголовку
Pragma: no-cache
Давайте теперь посмотрим, что нужно изменить в нашем сценарии, чтобы его вывод представлял из себя с точки зрения браузера не HTML-документ, а рисунок. Пусть нам нужен сценарий, который бы передавал пользователю какой-то GIF-рисунок (например, выбираемый случайным образом из некоторого списка). Делается это абсолютно аналогично: выводим заголовок
Content-type: image/gif
Затем копируем один-в-один нужный нам GIF-файл в стандартный поток вывода (лучше всего — функцией fwrite, т. к. иначе могут возникнуть проблемы с "бинарностью" GIF-рисунка). Теперь можно использовать этот сценарий даже в таком контексте:
... êàêîé-òî òåêñò ñòðàíèöû ...
<img src=http://www.myhost.com/cgi-bin/script.cgi>
... ïðîäîëæåíèå ñòðàíèöû ...
В результате таких действий в нашу страницу будет подставляться каждый раз случайное изображение, генерируемое сценарием. Разумеется, чтобы избежать неприятностей с кэшированием, которое особенно интенсивно применяется браузерами по отношению к картинкам, мы должны его запретить выводом соответствующего заголовка. Именно так устроены графические счетчики, столь распространенные в Интернете.
Еще раз обращаю ваше внимание на такой момент: CGI-сценарии могут использоваться не только для вывода HTML-информации, но и для любого другого ее типа — начиная с графики и заканчивая звуковыми MIDI-файлами. Тип документа задается в единственном месте — заголовке Content-type. Не забывайте добавлять этот заголовок, в противном случае пользователю будет отображена стандартная страница сервера с сообщением о 500-й ошибке (для сервера Apache), из которой он вряд ли что поймет.