开发者

Missing characters from input stream from fastcgi request

开发者 https://www.devze.com 2023-01-26 19:24 出处:网络
I\'m trying to develop simple RESTful api using FastCGI (and restcgi). When I tried to implement POST method I noticed that the input stream (representing request body) is wrong. I did a little test a

I'm trying to develop simple RESTful api using FastCGI (and restcgi). When I tried to implement POST method I noticed that the input stream (representing request body) is wrong. I did a little test and looks like when I try to read the stream only every other character is received.

Body sent: name=john&surname=smith Received: aejh&unm=mt

I've tried more clients just to make sure it's not the client messing with the data. My code is:

int main(int argc, char* argv[开发者_开发问答]) {
  // FastCGI initialization.
  FCGX_Init();
  FCGX_Request request;
  FCGX_InitRequest(&request, 0, 0); 

  while (FCGX_Accept_r(&request) >= 0) {
    // FastCGI request setup.
    fcgi_streambuf fisbuf(request.in);
    std::istream is(&fisbuf);
    fcgi_streambuf fosbuf(request.out);
    std::ostream os(&fosbuf);

    std::string str;
    is >> str;
    std::cerr << str;  // this way I can see it in apache error log

    // restcgi code here
  }   

  return 0;
}

I'm using fast_cgi module with apache (not sure if that makes any difference).

Any idea what am I doing wrong?


The problem is in fcgio.cpp

The fcgi_steambuf class is defined using char_type, but the int underflow() method downcasts its return value to (unsigned char), it should cast to (char_type).


I encountered this problem as well, on an unmodified Debian install.

I found that the problem went away if I supplied a buffer to the fcgi_streambuf constructor:

const size_t LEN = ... // whatever, it doesn't have to be big.
vector<char> v (LEN);
fcgi_streambuf buf (request.in, &v[0], v.size());
iostream in (&buf);
string s;
getline(in, s); // s now holds the correct data.


After finding no answer anywhere (not even FastCGI mailing list) I dumped the original fastcgi libraries and tried using fastcgi++ libraries instead. The problem disappeared. There are also other benefits - c++, more features, easier to use.


Use is.read() not is >> ...

Sample from restcgi documentation:

clen = strtol(clenstr, &clenstr, 10);
if (*clenstr)
{
    cerr << "can't parse \"CONTENT_LENGTH="
          << FCGX_GetParam("CONTENT_LENGTH", request->envp)
          << "\"\n";
    clen = STDIN_MAX;
}

// *always* put a cap on the amount of data that will be read
if (clen > STDIN_MAX) clen = STDIN_MAX;

*content = new char[clen];

is.read(*content, clen);
clen = is.gcount();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号