Question

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::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?

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

Was it helpful?

Solution

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

But look closer:

until the streambuf's get area contains ...

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top