问题 如何使用fastcgi C / C ++应用程序访问POST请求的主体


我正在使用一个库 http://fastcgi.com/ 在C ++应用程序中作为后端和nginx Web服务器作为前端。

成功发布HTML表单中的文件,可以在nginx服务器端查看临时文件。但我无法弄清楚如何使用fastcgi_stdio访问多部分POST请求的主体。这是我的HTML表单。

<html>
    <head>
        <title>Test Server</title>
        <script src="http://code.jquery.com/jquery.min.js"></script>
    </head>
    <body>
        <form id="upload-form" method="post" target="upload_target"   enctype="multipart/form-data" action="/upload">
            <input name="file" id="file" size="27" type="file" /><br />
            <input type="submit" name="action" value="Upload" /><br />
            <iframe id="upload_target" name="upload_target" src="" style="width:100%;height:100px;border:0px solid #fff;"></iframe>
        </form>
    </body>
</html>

我的nginx conf文件:

location /upload {

# Pass altered request body to this location
upload_pass @test;

# Store files to this directory
# The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
upload_store /www/test;

# Allow uploaded files to be read only by user
upload_store_access user:rw group:r all:r;

# Set specified fields in request body
upload_set_form_field $upload_field_name.name $upload_file_name;
upload_set_form_field $upload_field_name.content_type "$upload_content_type";
upload_set_form_field $upload_field_name.path "$upload_tmp_path";

# Inform backend about hash and size of a file
upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

upload_pass_form_field "^submit$|^description$";
upload_cleanup 400 404 499 500-505;
}

include fastcgi.conf;

# Pass altered request body to a backend
location @test {
        fastcgi_pass  localhost:8080
}

现在,如何处理/获取我的fastcgi c ++应用程序中的POST请求主体以及如何在fastcgi应用程序端的适当文件中编写它?

有没有更好的快速模块来实现这一目标?

谢谢。


9220
2017-10-18 12:05


起源



答案:


你可以访问 POST 身体通过 FCGI_stdin 流。例如,您可以使用一次读取一个字节 FCGI_getchar,这是一个简短的形式 FCGI_fgetc(FCGI_stdin)。您可以使用单个调用读取更大的数据块 FCGI_fread。所有这些我发现了 来源。这些来源经常引用一种叫做“H&S”的东西 - 这代表着本书的作者“Harbison and Steele” C:参考手册,这些数字指的是该书的章节。

顺便说一句,它被称为“标准输入/输出”的“stdio”。不是“工作室”。这些功能应该主要与没有功能的功能相同 FCGI_ 前缀。所以有关详细信息,请查看手册页 getcharfread 等等。

一旦在应用程序中有字节,就可以使用普通的stdio操作或通过打开的文件将它们写入文件 FCGI_fopen。但请注意,输入流不会直接对应于上载文件的内容。相反,MIME编码用于传输所有表单数据,包括文件。你必须这样做 解析该流 如果要访问文件数据。


12
2017-10-18 14:10



谢谢您的帮助。会尝试这个。但有一个问题nginx总是在打开到FCGI的连接之前缓冲请求体。有没有办法将该缓冲区直接重定向到FCGI?或者一旦缓冲完成,通过连接将文件内容发送到后端?(这将减少解析的空白,因为Nginx正在这样做。)如果我的理解错误,请纠正我。再次感谢。 - user1495653
@ user1495653:我对Nginx几乎一无所知,但我认为没有理由解析它缓冲的数据。我会假设HTTP服务器一旦检测到标题的结尾就停止关注内容。所以我提到的方法可能已经从缓冲区读取了,你将是第一个真正解析这些数据的方法。 - MvG
好。但我想再次知道c / C ++中是否有一些模块可以给我requestHandler和一些方法来使用处理程序访问请求信息?我想有一些模块可用于PHP,Ruby等。 - user1495653
@ user1495653:我链接的帖子有一个答案暗示 这个问题。 这个问题 几乎同样问道。可能会有更多。 - MvG


答案:


你可以访问 POST 身体通过 FCGI_stdin 流。例如,您可以使用一次读取一个字节 FCGI_getchar,这是一个简短的形式 FCGI_fgetc(FCGI_stdin)。您可以使用单个调用读取更大的数据块 FCGI_fread。所有这些我发现了 来源。这些来源经常引用一种叫做“H&S”的东西 - 这代表着本书的作者“Harbison and Steele” C:参考手册,这些数字指的是该书的章节。

顺便说一句,它被称为“标准输入/输出”的“stdio”。不是“工作室”。这些功能应该主要与没有功能的功能相同 FCGI_ 前缀。所以有关详细信息,请查看手册页 getcharfread 等等。

一旦在应用程序中有字节,就可以使用普通的stdio操作或通过打开的文件将它们写入文件 FCGI_fopen。但请注意,输入流不会直接对应于上载文件的内容。相反,MIME编码用于传输所有表单数据,包括文件。你必须这样做 解析该流 如果要访问文件数据。


12
2017-10-18 14:10



谢谢您的帮助。会尝试这个。但有一个问题nginx总是在打开到FCGI的连接之前缓冲请求体。有没有办法将该缓冲区直接重定向到FCGI?或者一旦缓冲完成,通过连接将文件内容发送到后端?(这将减少解析的空白,因为Nginx正在这样做。)如果我的理解错误,请纠正我。再次感谢。 - user1495653
@ user1495653:我对Nginx几乎一无所知,但我认为没有理由解析它缓冲的数据。我会假设HTTP服务器一旦检测到标题的结尾就停止关注内容。所以我提到的方法可能已经从缓冲区读取了,你将是第一个真正解析这些数据的方法。 - MvG
好。但我想再次知道c / C ++中是否有一些模块可以给我requestHandler和一些方法来使用处理程序访问请求信息?我想有一些模块可用于PHP,Ruby等。 - user1495653
@ user1495653:我链接的帖子有一个答案暗示 这个问题。 这个问题 几乎同样问道。可能会有更多。 - MvG


用这个:

char * method = getenv("REQUEST_METHOD");
if (!strcmp(method, "POST")) {
    int ilen = atoi(getenv("CONTENT_LENGTH"));
    char *bufp = malloc(ilen);
    fread(bufp, ilen, 1, stdin);
    printf("The POST data is<P>%s\n", bufp);
    free(bufp);
}

2
2017-11-18 23:42