【问题标题】:how to access a body of POST request using fastcgi C/C++ application如何使用 fastcgi C/C++ 应用程序访问 POST 请求的主体
【发布时间】:2012-10-08 21:13:27
【问题描述】:

我在 C++ 应用程序中使用来自 http://fastcgi.com/ 的库作为后端,使用 nginx 网络服务器作为前端。

从 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 配置文件:

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 应用程序端将其写入适当的文件中?

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

谢谢。

【问题讨论】:

    标签: c++ c web-applications nginx fastcgi


    【解决方案1】:

    您可以通过FCGI_stdin 流访问POST 正文。例如,您可以使用FCGI_getchar 一次读取一个字节,这是FCGI_fgetc(FCGI_stdin) 的缩写形式。您可以使用FCGI_fread 在一次调用中读取更大的数据块。我发现所有这些都是看着the source。这些消息来源经常引用名为“H&S”的东西——它代表“Harbison and Steele”,这本书的作者 C: A Reference Manual,数字指的是该书的章节。

    顺便说一下,它被称为“stdio”,表示“标准输入/输出”。不是“工作室”。这些函数的行为应该与没有 FCGI_ 前缀的对应函数一样。所以详情请看getcharfread等的man page。

    在应用程序中获得字节后,您可以使用普通的 stdio 操作或通过FCGI_fopen 打开的文件将它们写入文件。但是请注意,输入流不会直接对应于上传文件的内容。相反,MIME 编码用于传输所有表单数据,包括文件。如果你想访问文件数据,你必须parse that stream

    【讨论】:

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

    使用这个:

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      • 2014-11-01
      • 2012-06-24
      相关资源
      最近更新 更多