Сервер Web своими руками. Язык HTML, приложения CGI и ISAPI

       

Программа COUNTER


Почти на каждом сервере WWW в сети Internet вы можете встретить счетчик посещений. По его показаниям можно судить о посещаемости сервера, что имеет, например, значение при выборе сервера для размещения рекламы.

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

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

Пример такого файла шаблона вы можете найти в листинге 7.9.

Листинг 7.9. Файл chap7\counter\home.tm

<HTML>

  <BODY BGCOLOR="#FFFFFF">

    <H1>Главная страница фирмы XYZ Inc.</H1>

    <P>Добро пожаловать на нашу главную страницу!

    <HR>

    <P>Вы посетитель номер <B>~~~~~</B> с 1 января 1913 года

  </BODY>

</HTML>



Мы назвали файл home.tm, хотя вы можете выбирать для файлов шаблона любые имена.

Далее вам нужно сделать ссылку на документ, содержащий счетчик. Такая ссылка указывает на программу CGI, выполняющую подсчет посещений. В листинге 7.10 ссылка на программу счетчика выполнена с использованием оператора <A>.

Листинг 7.10. Файл chap7\counter\default.htm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">

<HTML>

  <HEAD>

    <TITLE>Счетчик посещений</TITLE>

  </HEAD>

  <BODY BGCOLOR=#FFFFFF>

    <H1>Посетите нашу главную страницу</H1>

    <A HREF="http://frolov/frolov-cgi/counter.exe?">Главная страница</A><BR>


  </BODY>

</HTML>

Внешний вид этого документа показан на рис. 7.10.



Рис. 7.10. Документ, который содержит ссылку на программу CGI, отображающую главную страницу

Обратите внимание, что вслед за именем программы мы разместили разделительный символ “?”, после которого вы можете указывать дополнительные параметры, например, номер счетчика. Это может пригодиться, если ваша программа CGI должна выполнять отдельный подсчет посещений для различных документов HTML.

Получив управление, программа счетчика может считать файл шаблона в оперативную память, найти там поле счетчика и заменить его на текущее количество посещений.

А как подсчитывать посещения?

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

После того как текущее значение счетчика посещений будет записано в соответствующее поле шаблона, программа счетчика может вывести шаблон в стандартный поток вывода STDOUT.

Документ HTML, полученный таким образом из нашего шаблона, показан на рис. 7.11.



Рис. 7.11. Документ HTML со счетчиком, созданный динамически на базе файла шаблона

Исходный текст программы COUNTER, работающей с использованием описанного выше алгоритма, приведен в листинге 7.11.

Листинг 7.11. Файл chap7\counter\counter.c

// ===============================================

// Программа CGI counter.c

// Реализация счетчика посещений

//

// (C) Фролов А.В., 1997

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//         или

//         http://www.dials.ccas.ru/frolov

// ===============================================

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <io.h>

#include <fcntl.h>



void main(int argc, char *argv[])

{

  // Идентификатор файла шаблона главной страницы

  HFILE hSrcFile;

  // Идентификатор файла счетчика

  FILE *CounterFile;

  // Размер файла шаблона

  DWORD dwFileSize;

  // Адрес шаблона главной страницы

  LPSTR szTemplate;

  // Временный буфер для работы со счетчиком

  CHAR  szBuf[10];

  // Текущее значение счетчика

  INT   nCounter;

  // Указатель на поле счетчика в шаблоне

  LPSTR szCounterPtr;

  // -----------------------------------------------

  // Считываем файл шаблона в оперативную память

  // -----------------------------------------------

 

  // Открываем файл шаблона

  hSrcFile = _lopen("HOME.TM", OF_READ);

 

  // Определяем размер файла в байтах

  dwFileSize = _llseek(hSrcFile, 0, 2);

  // Устанавливаем указатель текущей позиции

  // на начало файла шаблона

  _llseek(hSrcFile, 0, 0);

  // Получаем память для буфера шаблона

  szTemplate = malloc(dwFileSize);

  // Загружаем шаблон в буфер

  _hread(hSrcFile, szTemplate, dwFileSize);

   

  // -----------------------------------------------

  // Увеличиваем значение счетчика в файле

  // -----------------------------------------------

 

  // Открываем файл счетчика для чтения

  CounterFile = fopen("CNTDAT.DAT", "r");

  // Читаем из файла строку значения счетчика

  fgets(szBuf, 7, CounterFile);

  // Закрываем файл счетчика

  fclose(CounterFile);

 

  // Преобразуем значение счетчика из текстовой

  // строки в численную величину

  sscanf(szBuf, "%d", &nCounter);

 

  // Увеличиваем значение счетчика

  nCounter++;

 

  // Записываем в буфер szBuf пять цифр нового

  // значения счетчика

  sprintf(szBuf, "%05.5ld", nCounter);

  // Сохраняем новое значение счетчика в файле

  CounterFile = fopen("CNTDAT.DAT", "w");

  fprintf(CounterFile, "%d", nCounter);



  fclose(CounterFile);

  // -----------------------------------------------

  // Заменяем 5 цифр значения счетчика на новые

  // в буфере шаблона

  // -----------------------------------------------

  // Ищем маркер поля счетчика

  szCounterPtr = strstr(szTemplate, "~~~~~");

 

  // Копируем в это поле новое значение счетчика

  if(szCounterPtr != NULL)

    strncpy(szCounterPtr, szBuf, 5);

 

  // Выводим заголовок HTTP и разделительную строку

  printf("Content-type: text/html\n\n");

  // Выводим шаблон с измененным значением

  // поля счетчика

  fwrite(szTemplate, dwFileSize, 1, stdout);

  // Освобождаем буфер шаблона   

  free(szTemplate);

}

Получив управление, программа COUNTER считывает файл шаблона в оперативную память. Для упрощения исходного текста программы мы применили для работы с файлом функции _lopen, _llseek и _hread, которые являются специфичными для операционной системы Microsoft Windows. Вы можете использовать здесь любые другие функции, предназначенные для работы с файлами.

Перед чтением файла шаблона мы определяем его длину в байтах, для чего используем известный прием с установкой текущей позиции на конец файла функцией _llseek. После того как размер файла будет сохранен в переменной dwFileSize, текущая позиция снова устанавливается на начало файла шаблона. Вслед за этим программа CGI динамически заказывает память для буфера и читает в этот буфер файл шаблона за один вызов функции  _hread.

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

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

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

После обновления шаблона в стандартный поток вывода записывается обычный заголовок HTTP (функцией printf) и шаблон (функцией fwrite). На последнем этапе освобождается буфер памяти, заказанный для буфера шаблона.


Содержание раздела