通过读取stdin的http POST(C中的CGI)

时间:2010-07-11 10:04:59

标签: c cgi

哪种在C中用CGI获取http POST的无错误方法?

我目前正在使用此功能。好吗?如果“CONTENT_LENGTH”不正确并且大于stdin,该怎么办?那读书会怎么样呢?


char *STDIN = NULL;
char *pointer = getenv("CONTENT_LENGTH");
if(pointer != NULL)
{
    char charlength[5] = "";
    strncat(charlength, pointer, 4); // limit length to a reasonable number
    unsigned long int length = strtoul(charlength, NULL, 0);
    STDIN = malloc(length + 2);
    ssize_t readbytes = read(0, STDIN, length);
    STDIN[readbytes] = '&'; // for use later on in my program
    memset(STDIN + readbytes + 1, (int)'\0', (length + 2) - (size_t)(readbytes + 1));
}

2 个答案:

答案 0 :(得分:2)

read(2)将返回不超过您要求的字节数。这可能会在stdin文件描述符中留下更多数据用于读取(如果客户端发送CONTENT_LENGTH为0但是将其发送给/ dev / urandom),但这没关系。你的过程可以自由地消失,而不是全部阅读。

read(2)可能返回的字节数比您要求的少。这可能是因为并非所有数据都已到达且内核已厌倦阻塞,或者内容可能小于CONTENT_LENGTH。我很高兴你把长度限制在'合理'的范围内,因为它很容易传入CONTENT_LENGTH,即最大size_t值,或者该值减去1,或者该值减去2,并且玩游戏使用malloc()分配0,1或2个字节,让你愉快地在你的记忆中涂鸦。

答案 1 :(得分:1)

您应该循环调用read

一般情况下都是如此,从套接字读取时尤其如此。中等到大量的数据很可能需要一段时间才能到达,但read通常会尽快返回(我不记得是否需要)。如果第一个TCP数据包包含大约1k的数据,那么第一次调用read可能会在下一个数据包到达之前返回1k,并且您当前的代码将永远不会读取其余数据。

因此,继续调用read(并且每次按照读取的字节数提前传入的指针,并减少同样读取的字节数),直到满足以下条件之一:

  • 您已经阅读了CONTENT_LENGTH个字节。
  • read返回0(在这种情况下,POST数据比CONTENT_LENGTH承诺的要短)。
  • read返回-1(表示发生了错误),errno不是EINTR(或EAGAIN,如果设置了O_NONBLOCK,在这种情况下你会想要睡觉或类似在下一次阅读之前。但在这种情况下设置O_NONBLOCK没有意义。)