boost read_until不会在分隔符处停止

时间:2020-12-14 23:57:55

I'm using the boost read_until function to facilitate receiving and parsing HTTP messages over a socket. So what I'm trying to do is read_until from the socket until \r\n, which I think should give me one line of the HTTP header. (Each HTTP header line ends in \r\n, per the standard.) However, what I'm actually getting from read_line instead is the entire header, several lines long. (The header ends in \r\n\r\n, or in other words, a blank line. Also, per the HTTP standard.) Here's a code snippet. sock is the socket file descriptor.

我正在使用boost read_until函数来促进通过套接字接收和解析HTTP消息。所以我要做的是从套接字read_until直到\ r \ n,我认为应该给我一行HTTP标头。 (根据标准,每个HTTP标题行以\ r \ n结尾。)然而,我实际上从read_line获得的是整个标题,多行为多行。 (标题以\ r \ n \ n \ n \ n结尾,或者换句话说,空白行。另外,根据HTTP标准。)这是一段代码片段。 sock是套接字文件描述符。

boost::system::error_code err;
io::streambuf request_buff;

io::read_until(sock, request_buff, "\r\n", err); // read request line
if (err)
  throw Exception(string("Failed to read HTTP header request line from socket: ") + err.message());
cerr << "Read " << request_buff.size() << " bytes." << endl;

istream request(&request_buff);
try {
  request >> m_strMethod >> m_strPath >> m_strHttpVersion;

} catch (std::exception& e) {
  throw Exception(string("Failed to parse HTTP header: ") + e.what(), e);
}

if (!request)
  throw Exception("Failed to read HTTP header");
if (!alg::istarts_with(m_strHttpVersion, "HTTP/"))
  throw Exception(string("Malformed HTTP header: expected HTTP version but got: ") + m_strHttpVersion);

string strTemp;
while (std::getline(request, strTemp))
{
  cerr << "Extra line size = " << strTemp.size() << endl;
  cerr << "Extra line: '" << strTemp << '\'' << endl;
}

What I expect to see is output indicating it read the number of bytes in the first line of the HTTP message and no "Extra" output. What I get instead is the number of bytes in the entire HTTP header, and a blank extra line (which maybe is because the >> operations didn't consume the newline at the end of the first line) followed by every other line in the header, and another blank line (which indicates the end of the header, as noted above). Why is read_until reading more from the socket than the first line of the header and putting it into request_buff?

我期望看到的是输出,表明它读取了HTTP消息第一行中的字节数,没有“额外”输出。我得到的是整个HTTP头中的字节数,以及一个空白的额外行(这可能是因为>>操作没有消耗第一行末尾的换行符),后面是其他每一行标题和另一个空行(表示标题的结尾,如上所述)。为什么read_until从套接字读取的内容比标题的第一行更多并将其放入request_buff?

Note, I used netcat to receive the request and it's coming through okay. So the HTTP message itself appears to be correctly formatted.

注意,我使用netcat接收请求,它正好通过。因此,HTTP消息本身似乎已正确格式化。

1 个解决方案

#1


3  

The documentation may seem to imply this:

文档似乎暗示了这一点:

"This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter."

“此函数用于将数据读入指定的streambuf,直到streambuf的get区域包含指定的分隔符。”

But look closer:

但仔细看看:

until the streambuf's get area contains ...

直到streambuf的获取区域包含...

So, it doesn't promise to stop there. It just promises to return to you as soon as it read the block that contains your delimiter.

所以,它不承诺停在那里。它只是承诺在读取包含分隔符的块时立即返回给您。

#1


3  

The documentation may seem to imply this:

文档似乎暗示了这一点:

"This function is used to read data into the specified streambuf until the streambuf's get area contains the specified delimiter."

“此函数用于将数据读入指定的streambuf,直到streambuf的get区域包含指定的分隔符。”

But look closer:

但仔细看看:

until the streambuf's get area contains ...

直到streambuf的获取区域包含...

So, it doesn't promise to stop there. It just promises to return to you as soon as it read the block that contains your delimiter.

所以,它不承诺停在那里。它只是承诺在读取包含分隔符的块时立即返回给您。