php - Http 服务器使用 C++ 将数据发布到 php-cgi

标签 php c++

我正在编写一个简单的 http 服务器,我想使用 php-cgi 来处理 POST 请求。我将 handlePOST 写成如下:

void KServer::handlePOST(int sockfd, string file, string pdata){
    char* argvs[MAX_PARAMS];
    argvs[0] = const_cast<char*>(CGI_PATH);
    argvs[1] = const_cast<char*>(file.c_str());

    stringstream ss;
    ss<<pdata.length();
    string clen, sname;
    ss>>clen;
    clen = "CONTENT_LENGTH=" + clen;
    sname = "SCRIPT_FILENAME="+file;

    char* env[] = {
            "REQUEST_METHOD=POST",
            "REDIRECT_STATUS=CGI",
            const_cast<char*>(clen.c_str()),
            const_cast<char*>(sname.c_str()),
            "CONTENT_TYPE=application/x-www-form-urlencoded",
            0
    };


    istringstream stream(pdata);
    cin.rdbuf(stream.rdbuf());

    execve(argvs[0], argvs, env);
    ...

我知道 php-cgiSTDIN 获取 POST 数据。然后我将 POST 数据 (var. pdata) 放入 cin.rdbuf。但是,程序在执行 execve 时无法从 STDIN 获取数据。但是如果我使用控制台输入字符串,程序可以正确运行。

最佳答案

当您的自定义 HTTP 服务器读取套接字时,它不太可能总是设法在到达这一点之前准确读取 HTTP 消息 header 部分中的字节数;因此,当它执行外部进程时,包含 POST 数据的消息正文部分现在正等待在其标准输入上读取。

很有可能,您正在使用 C++ I/O 库,甚至可能是 C stdio 库来读取标准输入或套接字。当然,这意味着 iostreamsstdio 所采用的内置输入缓冲已经设法吞下了很大一部分 POST 来自 HTTP 消息正文的数据,紧跟在其 header 之后。它现在在等着你,继续阅读你的 std::cinstdin;或者您的代码实际读取的任何内容。

因此,可悲的是,当您执行外部进程时,它会沮丧地发现它所期望的 POST 数据已经全部或部分被消耗掉,它的标准输入。相反,它就坐在这里,在您的进程中,等待您继续阅读您的 std::cinstdin 或其他内容。

换句话说,要让它发挥作用,您不能只执行一个外部进程,然后就不用管整个烂摊子了。您将需要设置一个到外部进程标准输入的管道,您有责任继续仔细阅读构成 POST 数据的 HTTP 消息正文,就像您已经刚刚读完它的头,然后将它转储到管道中。

这意味着解析 Content-Length header ,以准确了解正文中有多少字节,并准确读取(因为您不会获得 EOF,并依赖它,因为套接字将保持打开状态用于您预期的 HTTP 回复)。

当然,您还需要仔细处理由于写入管道而发生的所有事情,即在消耗全部管道数据之前优雅地处理读取器关闭,从而导致管道损坏,等等……

关于php - Http 服务器使用 C++ 将数据发布到 php-cgi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36102026/

相关文章:

php - MySQL 自动增加主键作为外键

c++ - 警告 : 'struct curl_fileinfo' declared inside parameter list

c++ - OpenMP 隐式屏障

php - 计算最重复元素的算法;

php - 为什么这需要默认值?

php - if else 获取当前月份全名的 php 脚本

c++ - 相似但不相同的代码模板?

PHP Regex,从文本中提取所有自定义标签

c++ - C++ 运行时系统如何知道对象何时超出范围

c++ - opengl 计算人脸的法线