Microsoft Visual J++. Создание приложений и аплетов на языке Java

Исходные тексты программы CGI


В лситинге 3.10 мы привели исходный текст программы CGI с именем controls. Он несколько упрощен по сравнению с исходным текстом одноименного приложения, описанного в 29 томе “Библиотеки системного программиста” - мы выбросили обработку метода передачи данных GET,  так как наше приложение CallCGI передает данные только методом POST. Описание этой программы вы найдете в упомянутом 29 томе.

Листинг 3.10. Файл controls\controls.c

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

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

// Демонстрирует методы получения и обработки

// данных от форм, расположенных в документах HTML

//

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

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

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

//         или

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

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



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

// Прототипы функций перекодировки

void DecodeStr(char *szString);

char DecodeHex(char *str);

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

// Функция main

// Точка входа программы CGI

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

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

{

  int lSize;

  FILE * fileReceived;

  char * szMethod;

  char szBuf[8196];

  char szSrcBuf[8196];

  char * szPtr;

  char * szParam;

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

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

  // Вывод начального форагмента документа HTML,

  // формируемого динамически

  printf("<!DOCTYPE HTML PUBLIC"

    " \"-//W3C//DTD HTML 3.2//EN\">");

  printf("<HTML><HEAD><TITLE>Call CGI from Java"

    "</TITLE></HEAD><BODY BGCOLOR=#FFFFFF>");

  // Определяем метод передачи данных

  szMethod = getenv("REQUEST_METHOD");

  // Обработка метода POST

  if(!strcmp(szMethod, "POST"))

  {

    // Определяем размер данных, полученных от навигатора


    // при передаче данных из полей формы

    lSize = atoi(getenv("CONTENT_LENGTH"));

    // Читаем эти данные в буфер szBuf из

    // стандартного потока ввода STDIN

    fread(szBuf, lSize, 1, stdin);

    // Создаем файл, в который будут записаны

    // принятые данные

    fileReceived = fopen("received.dat", "w");

    // Выполняем запись принятых данных

    fwrite(szBuf, lSize, 1, fileReceived);

    // Закрываем файл принятых данных

    fclose(fileReceived);

    // Отображаем значения некоторых переменных среды

    printf("<H2>Environment variables</H2>");

   

    // Метод доступа

    printf("REQUEST_METHOD = %s", getenv("REQUEST_METHOD"));

    // Размер полученных данных в байтах

    printf("<BR>CONTENT_LENGTH = %ld", lSize);

    // Тип полученных данных

    printf("<BR>CONTENT_TYPE = %s", getenv("CONTENT_TYPE"));

    // Закрываем буфер данных двоичным нулем,

    // превращая его таким образом в строку

    szBuf[lSize] = '\0';

    // Делаем копию принятых данных в буфер szSrcBuf

    strcpy(szSrcBuf, szBuf);

    // Отображаем принятые данные без обработки

    printf("<H2>Received data</H2>");

    printf("<P>%s", szSrcBuf);

    // Выполняем перекодировку принятых данных

    DecodeStr(szSrcBuf);

    // Отображаем результат перекодировки

    printf("<H2>Decoded data</H2>");

    printf("<P>%s", szSrcBuf);

    // Выводим список значений полей формы

    printf("<H2>Filds list</H2>");

   

    // Дописываем в конец буфера принятых данных

    // символ "&", который используется в качестве

    // разделителя значений полей

    szBuf[lSize] = '&';

    szBuf[lSize + 1] = '\0';

    // Цикл по полям формы



    for(szParam = szBuf;;)

    {

      // Ищем очередной разделитель

      szPtr = strchr(szParam, '&');

     

      // Если он найден, раскодируем строку параметров

      if(szPtr != NULL)

      {

        *szPtr = '\0';

        DecodeStr(szParam);

     

        // Выводим в документ значение параметра

        printf("%s<BR>", szParam);

        // Переходим к следующему параметру

        szParam = szPtr + 1;

        // Если достигнут конец буфера, завершаем цикл

        if(szParam >= (szBuf + lSize))

          break;

      }

      else

        break;

    }

   

    // Выводим завершающий фрагмент документа HTML

    printf("</BODY></HTML>");

    return;

  }

}

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

// Функция DecodeStr

// Раскодирование строки из кодировки URL

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

void DecodeStr(char *szString)

{

  int src;

  int dst;

  char ch;

  // Цикл по строке

  for(src=0, dst=0; szString[src]; src++, dst++)

  {

    // Получаем очередной символ перекодируемой строки

    ch = szString[src];

    // Заменяем символ "+" на пробел

    ch = (ch == '+') ? ' ' : ch;

   

    // Сохраняем результат

    szString[dst] = ch;

   

    // Обработка шестнадцатеричных кодов вида "%xx"

    if(ch == '%')

    {

      // Выполняем преобразование строки "%xx"

      // в код символа

      szString[dst] = DecodeHex(&szString[src + 1]);

      src += 2;

    }

  }

 

  // Закрываем строку двоичным нулем

  szString[dst] = '\0';

}

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

// Функция DecodeHex

// Раскодирование строки "%xx"

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

char DecodeHex(char *str)

{

  char ch;

  // Обрабатываем старший разряд

  if(str[0] >= 'A')

    ch = ((str[0] & 0xdf) - 'A') + 10;

  else

    ch = str[0] - '0';

  // Сдвигаем его влево на 4 бита

  ch <<= 4;

  // Обрабатываем младший разряд и складываем

  // его со старшим

  if(str[1] >= 'A')

    ch += ((str[1] & 0xdf) - 'A') + 10;

  else

    ch += str[1] - '0';

  // Возвращаем результат перекодировки

  return ch;

}


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