How can I reuse http::response in beast

833 views Asked by At

I would like to periodically http GET some value from a website. with beast, the code is like:

// Set up an HTTP GET request message
http::request<http::string_body> req{http::verb::get, target, version};
req.set(http::field::host, host);
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
http::response<http::string_body> res;
while (true) {
    // Send the HTTP request to the remote host
    http::write(stream, req);
    
    res = {};
    // Receive the HTTP response
    http::read(stream, buffer, res);

    // Write the message to standard out
    std::cout << res << std::endl;
}

But in the loop,

res = {}

brought one temporary object creation, one move/copy assignment and the destroy of the temporary object. I am wondering if there is a better way to avoid these unnecessary costs。

3

There are 3 answers

1
Paul Sanders On

Just remove the offending line and move the declaration of res inside the while loop. res will then be created and destroyed each time round the loop:

// Set up an HTTP GET request message
http::request<http::string_body> req{http::verb::get, target, version};
req.set(http::field::host, host);
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);

while (true) {
    // Send the HTTP request to the remote host
    http::write(stream, req);
    
    // Receive the HTTP response
    http::response<http::string_body> res;
    http::read(stream, buffer, res);

    // Write the message to standard out
    std::cout << res << std::endl;
}
1
sehe On

You can replace res = {}; with res.clear(); or drop it altogether.

The read free function instantiates a parser that takes ownership of all response resources (by move)¹. In its constructor, it unconditionally clears the message object anyways:

enter image description here

You can use a debugger to trace through these lines with a simple tester like this, which is exactly what I did.


¹ in the end the message is moved back into the response object passed, so it works out

0
user17827718 On

Here's what I would do

http::read(stream, buffer, res);
// move the response object to the processing function
process(std::move(res)); // res will be as clean as newly constructed after being moved