【问题标题】:Missing characters from input stream from fastcgi request来自 fastcgi 请求的输入流中缺少字符
【发布时间】:2010-11-25 21:31:42
【问题描述】:

我正在尝试使用 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;
}

我在 apache 中使用 fast_cgi 模块(不确定这是否有什么不同)。

知道我做错了什么吗?

【问题讨论】:

  • 似乎是每跳过一个字符(16/8 位)的编码问题
  • 但是怎么做呢?如果它将 2B 解释为一个字符,那么字符将是别的东西,但在我的情况下它是正确的......

标签: c apache fastcgi


【解决方案1】:

问题出在 fcgio.cpp 中

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

【讨论】:

  • 这似乎确实解决了问题,但我不太明白为什么在返回之前将其转换为 unsigned char 会导致所有其他字符消失
【解决方案2】:

我在未修改的 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.

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      使用is.read() 而不是is &gt;&gt; ...

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

      【讨论】:

        猜你喜欢
        • 2015-01-19
        • 1970-01-01
        • 2021-03-09
        • 1970-01-01
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多