fastcgi 请求的输入流中缺少字符

发布于 2024-10-04 02:38:54 字数 877 浏览 1 评论 0原文

我正在尝试使用FastCGI(和restcgi)开发简单的RESTful api。当我尝试实现 POST 方法时,我注意到输入流(表示请求正文)是错误的。我做了一些测试,看起来当我尝试读取流时,只收到了所有其他字符。

正文已发送:name=john&surname=smith 收到:aejh&unm=mt

我尝试了更多客户端,只是为了确保不是客户端弄乱了数据。 我的代码是:

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

我正在将 fast_cgi 模块与 apache 一起使用(不确定这是否有任何区别)。

知道我做错了什么吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ぶ宁プ宁ぶ 2024-10-11 02:38:54

问题出在 fcgio.cpp 中的

fcgi_steambuf 类是使用 char_type 定义的,但是 int underflow() 方法将其返回值向下转换为 >(unsigned char),它应该转换为 (char_type)

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).

谁许谁一生繁华 2024-10-11 02:38:54

我在未修改的 Debian 安装上也遇到了这个问题。

我发现如果我向 fcgi_streambuf 构造函数提供缓冲区,问题就会消失:

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.

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.
以可爱出名 2024-10-11 02:38:54

在任何地方都找不到答案(甚至没有 FastCGI 邮件列表)后,我转储了原始的 fastcgi 库并尝试使用 fastcgi++ 库。问题消失了。还有其他好处——c++,功能更多,更容易使用。

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.

錯遇了你 2024-10-11 02:38:54

使用 is.read() 而不是 is >> ...

来自restcgi文档的示例:

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

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文