Чтение данных из стандартного потока ввода
При передаче запроса по методу 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(). При этом не следует ожидать существенного уменьшения времени чтения данных. Во-первых, данные при вводе буферизуются. Во-вторых, в С применяется потоковая модель работы с внешними наборами данных.