在fastCGI中重定向URL时合并消息体?

时间:2016-11-04 12:10:21

标签: c++ nginx fastcgi

我在c ++中使用nginx实现fastCGI。到现在为止,我能够开发基本的http请求方法和一些url重定向。但是,在从post url重定向到另一个post url时,我无法发送消息正文。以下是我的代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <sstream>
    #include <iostream>
    #include <string>
    #include "string.h"
    #include "fcgio.h"
    #include <fcgi_stdio.h>
    #include <boost/algorithm/string.hpp>

    using namespace std;
    using namespace boost;

    // Maximum bytes
    const unsigned long STDIN_MAX = 1000000;

    /**
     * Note this is not thread safe due to the static allocation of the
     * content_buffer.
     */
    string get_request_content(const FCGX_Request & request) {
        char * content_length_str = FCGX_GetParam("CONTENT_LENGTH", request.envp);
        unsigned long content_length = STDIN_MAX;

        if (content_length_str) {
            content_length = strtol(content_length_str, &content_length_str, 10);
            if (*content_length_str) {
                cerr << "Can't Parse 'CONTENT_LENGTH='"
                     << FCGX_GetParam("CONTENT_LENGTH", request.envp)
                     << "'. Consuming stdin up to " << STDIN_MAX << endl;
            }

            if (content_length > STDIN_MAX) {
                content_length = STDIN_MAX;
            }
        } else {
            // Do not read from stdin if CONTENT_LENGTH is missing
            content_length = 0;
        }

        char * content_buffer = new char[content_length];
        cin.read(content_buffer, content_length);
        content_length = cin.gcount();

        // Chew up any remaining stdin - this shouldn't be necessary
        // but is because mod_fastcgi doesn't handle it correctly.

        // ignore() doesn't set the eof bit in some versions of glibc++
        // so use gcount() instead of eof()...
        do cin.ignore(1024); while (cin.gcount() == 1024);

        string content(content_buffer, content_length);
        delete [] content_buffer;
        return content;
    }

    int main(void) {
        // Backup the stdio streambufs
        streambuf * cin_streambuf  = cin.rdbuf();
        streambuf * cout_streambuf = cout.rdbuf();
        streambuf * cerr_streambuf = cerr.rdbuf();

        FCGX_Request request;

        FCGX_Init();
        FCGX_InitRequest(&request, 0, 0);


        while (FCGX_Accept_r(&request) == 0) {
            fcgi_streambuf cin_fcgi_streambuf(request.in);
            fcgi_streambuf cout_fcgi_streambuf(request.out);
            fcgi_streambuf cerr_fcgi_streambuf(request.err);

            cin.rdbuf(&cin_fcgi_streambuf);
            cout.rdbuf(&cout_fcgi_streambuf);
            cerr.rdbuf(&cerr_fcgi_streambuf);

            const char * uri = FCGX_GetParam("REQUEST_URI", request.envp);

            string content = get_request_content(request);

            if (content.length() == 0) {
                content = ", something!";
            }
            const char * mediaType = FCGX_GetParam("REQUEST_METHOD",request.envp);
            string value;
            if(iequals(mediaType,"POST")&&iequals(uri,"/postmethod")) {

                get_request_content(request);
                 cout << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
            }

            if(iequals(mediaType,"GET")&&iequals(uri,"/getmethod")) {

                string aalu = "this is the new lenght";
                 cout << "HTTP/1.1 200 OK\r\nContent-Length: " << aalu.length() << "\r\n\r\n" << aalu;
                 FCGX_Finish_r(&request);
            }

            if(iequals(mediaType,"GET")&&iequals(uri,"/redirect")) {

                cout << "HTTP/1.1 301\r\nLocation: http://localhost/getmethod\r\n\r\n";
//              cout << "Status: 301\r\n"
        //                       << "Location: http://localhost/getmethod\r\n";
        //                       << "\r\n";
        //                       << "<html><body>Not Found</body></html>\n";
            }

            if(iequals(mediaType,"GET")&&iequals(uri,"/postredirect")) {     // problem here

                string json = "{\"topic\":\"asdf\",\"message\":\"message\"}";
                cout << "HTTP/1.1 308\r\nLocation: http://localhost/postmethod\r\n\r\n";
//              cout << "Status: 304\r\n"
//                      << "Location: http://localhost/postmethod\r\n"
//                        << "\r\n"
//                          << "<html><body>json</body></html>\n";
            }

            if(iequals(mediaType,"POST")&&iequals(uri,"/getredirect")) {

                            string json = "{\"topic\":\"asdf\",\"message\":\"message\"}";
                            cout << "HTTP/1.1 303\r\nLocation: http://localhost/getmethod\r\n\r\n";
            //              cout << "Status: 304\r\n"
            //                      << "Location: http://localhost/postmethod\r\n"
            //                        << "\r\n"
            //                          << "<html><body>json</body></html>\n";
                        }

            if(iequals(mediaType,"POST")&&iequals(uri,"/posttopostredirect")) {


                                    string json = "{\"topic\":\"adf\",\"message\":\"message\"}";

                                    cout << "Status: 307\r\n"
                                            <<"Location: http://localhost/postmethod\r\n"
                                                <<"\r\n"
                                                <<"\n";

//                                  cout << "Status: 305\r\n"
//                                          << "Location: http://localhost/postmethod\r\n"
//                                            << "\r\n"
//                                              << "<html><body>"+json+"</body></html>\n";
                                }

            if(iequals(mediaType,"GET")&&iequals(uri,"/getttogettredirect")) {

                                                string json = "{\"topic\":\"ssdf\",\"message\":\"message\"}";
                                                cout << "HTTP/1.X 301\r\nLocation: http://localhost/getmethod\r\n\r\n";
            //                                  cout << "Status: 307\r\n"
            //                                          << "Location: http://localhost/postmethod\r\n"
            //                                            << "\r\n";
            //                                              << "<html><body>json</body></html>\n";
                                            }
        }

        // restore stdio streambufs
        cin.rdbuf(cin_streambuf);
        cout.rdbuf(cout_streambuf);
        cerr.rdbuf(cerr_streambuf);

        return 0;
    }

/ posttopostredirect url重定向到/ postmethod url。在这里,我希望在/ posttopostredirect被命中/ postmethod url时发送json字符串(上面)。但无法弄清楚如何做到这一点

1 个答案:

答案 0 :(得分:0)

完全忽略HTTP重定向消息的任何内容。这与FastCGI无关。这就是HTTP的工作原理。 HTTP重定向消息不能用于发送任何内容。好吧,他们可以,但HTTP客户端会忽略它,并向重定向到的URL发出GET请求。

唯一可以做的是将任何数据包含在重定向到的URL中编码的参数中。这与编码URL中的任何参数的方式相同。