Российский государственный гуманитарный университет
Опубликован: 15.08.2003 | Доступ: свободный | Студентов: 6518 / 1489 | Оценка: 3.91 / 3.79 | Длительность: 06:55:00
Лекция 6:

Применение методов доступа HTTP в рамках программирования CGI-скриптов. Настройка HTTP-сервера для работы с CGI-скриптами

Чтение данных из стандартного потока ввода

При передаче запроса по методу POST от клиента к серверу передается HTTP-сообщение, которое состоит из заголовка и тела. Данные, введенные в HTML-форму, как раз и составляют тело сообщения. При обработке такого запроса CGI-скриптом данные следует выбирать из стандартного потока ввода скрипта, а не из переменной окружения QUERY_STRING. Эта переменная будет иметь пустое значение.

Для того, чтобы принять данные, нужно прочитать стандартный поток ввода. При этом из стандартного потока ввода нужно считать строго определенное количество байтов. Число байтов определяется переменной окружения CONTENT_LENGTH. В Perl прием данных в скрипт можно организовать следующим образом:

#!/usr/local/bin/perl
	read STDIN,$query,$ENV(CONTENT_LENGTH);

Здесь из стандартного потока ввода STDIN считывается $ENV(CONTENT_LENGTH) данных и помещается в переменную $query. После этого можно уже что-то делать с запросом, например, распечатать его в виде HTML-таблицы.

Аналогично можно принять запрос из стандартного ввода и в С. Для этого следует воспользоваться в простейшем случае функцией getchar():

#include <stdlib.h>
	#include <malloc.h>
	void main()
	{
	int n,i;
	char *buff;
	n = atoi(getenv("CONTENT_LENGTH"));
	buff = (char *) malloc(n+1);
	memset(buff,'\000',n+1);
	for(i=0;i<n;i++)
	{
	buff[i] = getchar();
	}
	printf("Content-type: text/plain\n\n");
	printf("Length of data into STDIN:%d\n",n);
	printf("STDIN data: %s\n",buff);
	free(buff);
	}

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

Передача присоединенных файлов

Метод POST позволяет реализовать передачу файлов с компьютера пользователя в архив на HTTP- сервере . Для этой цели разработана специальная форма кодирования тела документа: multipart/form-data. Она указывается в контейнере FORM в атрибуте ENCTYPE совместно с методом POST :

<FORM ENCTYPE=multipart/form-data 
        METHOD=post>

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

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

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

Очевидно, что метод POST с полями file-upload используется для опубликования данных на стороне сервера . При этом файл, который передается по сети, должен быть размещен в файловой системе либо сервера , либо другого удаленного компьютера. Для этого пользователь, от имени которого запускается скрипт, должен иметь соответствующие права на доступ к каталогу файловой системы компьютера, в который записывается файл. Довольно часто модули стандартных библиотек, например, CGI_Lite или CGI.pm, используют для временного хранения каталог /tmp. Иногда данный каталог закрывают на запись, из-за чего могут возникнуть проблемы с приемом данных скриптом, составленным из модулей стандартной библиотеки.