1
votes

I am trying to run my very first C++ CGI application. I use Ubuntu 14.04 and Apache 2.4.7. GET method works fine, the problem is when I try to do a POST method from a html form. The browser doesn't get a response. Logs files look like that:

apache2/access.log

[25/Feb/2015:10:30:05 +0100] "POST /cgi-bin/cgi-test.cgi HTTP/1.1" 200 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"

apache2/error.log

[Wed Feb 25 10:30:05.884648 2015] [cgid:error] [pid 1158:tid 139962890278656] (104)Connection reset by peer: [client 127.0.0.1:54871] AH02550: Failed to flush CGI output to client

The POST form code:

<form action="http://localhost/cgi-bin/cgi-test.cgi" method="post">
Test image: <input type="text" name="test">  <br />
<input type="submit" value="Submit" />
</form>

The GET form code:

<form action="http://localhost/cgi-bin/cgi-test.cgi" method="get">
Test image: <input type="text" name="test">  <br />
<input type="submit" value="Submit" />
</form>

And the C++ code:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

int main()
{
    std::cout << "Content-type: text/plain\n\n";

    char* get_query_data = getenv("QUERY_STRING");
    int l_result = -1;
    char* lenstr = getenv("CONTENT_LENGTH");
    if ( lenstr != NULL )
    {
        l_result = atoi(lenstr);
    }
    std::cout << "Post read length: " << l_result <<std::endl;
}

Does anyone have an idea that what is going wrong?

2

2 Answers

1
votes

I've had this happen when I wasn't reading all the POST data that's passed in. Apache reuses the same buffer for sending data to the CGI script and receiving from the CGI script. As a consequence, when Apache reads the response that you send back

("Content-type: text/plain\n\nPost read length: "),

part of the POST data is also still in the buffer

("Content-type: text/plain\n\nPost read length test=asdfjwkeqwersk598rsdf").

Apache detects that the response is malformed, so it fails to flush the output and closes the connection.

In summary, read ALL of the POST data from std::cin.

0
votes

I have never found why the code above crashes, but I finally implemented the POST method by using GNU Cgicc library.