当我在 on_read 上看到错误时,我应该清理野兽::flat_buffer吗?

问题描述 投票:0回答:1

http_client_async_ssl

class session : public std::enable_shared_from_this<session>
{
    ...
    beast::flat_buffer buffer_; // (Must persist between reads)
    http::response<http::string_body> res_;
    ...
}

void on_write(beast::error_code ec, std::size_t bytes_transferred) {

  if (ec)
  {
    fail(ec, "write");
    return try_again();    
  }    

  // Receive the HTTP response
  http::async_read(
      stream_, buffer_, res_,
      beast::bind_front_handler(&session::on_read, shared_from_this()));
}

void on_read(beast::error_code ec, std::size_t bytes_transferred) {

  if (ec)
  {
    fail(ec, "read");
    return try_again();  
  }    

  // Step 1: process response
  //
  const auto &body_data = res_.body().data();
  user_parse_data(net::buffers_begin(body_data), net::buffers_end(body_data));
  
  // Step 2: clean up buffer_
  //
  buffer_.consume(buffer_.size()); // clean up buffer_ after finishing reading it

  // Step 3: continue to write
  ...
}

在上面的实现中,我仅在成功解析数据后才清理

buffer_

问题> 当我在

buffer_
上也遇到错误时,我应该清理
on_read
吗?

void on_read(beast::error_code ec, std::size_t bytes_transferred) {

  if (ec)
  {
    // clean up buffer_
    buffer_.consume(buffer_.size()); // Should we do the cleanup here too?
    
    fail(ec, "read");
    return try_again();    
  }    

  // Step 1: process response
  //
  const auto &body_data = res_.body().data();
  user_parse_data(net::buffers_begin(body_data), net::buffers_end(body_data));
  
  // Step 2: clean up buffer_
  //
  buffer_.consume(buffer_.size());

  // Step 3: continue to write
  ...
}
c++ boost boost-asio boost-beast beast-websockets
1个回答
2
投票
// Should we do the cleanup here too?

这完全是在问错误的问题。

首先出现的一个明显问题是“我们是否应该清理读取缓冲区”。

更重要的问题是:你用这个连接做什么?

缓冲区属于连接,因为它代表流数据。

您链接的示例始终会关闭连接。因此,缓冲区在收到响应后就变得无关紧要了——因为连接变得无关紧要。请注意,链接的示例也不在缓冲区上。


你应该清理吗?

您不应该

consume之后进行清理!

原因是
http::read

已经

消耗了解析为响应消息一部分的所有数据。
即使您希望从同一连接(例如 HTTP 管道)读取更多消息,您也需要

以相同的

http::read 开始下一个 http::read

,因为它可能已经包含后续消息的(部分)数据。 
出现错误怎么办?

如果您在 HTTP 传输过程中出现 IO/解析错误,我预计在大多数情况下 HTTP 协议规范将

要求

您关闭连接。

HTTP/1 中没有“try_again”。一旦丢失流内容的线程,就无法恢复到“已知状态”。

无论如何,我总是建议关闭失败的 HTTP 会话,因为不这样做会导致消息损坏和安全漏洞。

© www.soinside.com 2019 - 2024. All rights reserved.