Boost logo

Boost :

Subject: [boost] [beast] message bodies
From: Mike Gresens (mike.gresens_at_[hidden])
Date: 2017-07-02 17:33:45


Am 02.07.2017 um 02:22 schrieb Vinnie Falco via Boost:
>
>> * Similarly, as a user I'd prefer not to have string_body as a distinct
>> type (unless it's a convenience typedef for dynamic_body<std::string>). If
>> std::string is not a model of DynamicBuffer, I think DynamicBuffer could
>> stand a slight reformulation.
> std::string does not model DynamicBuffer, which itself is a Net-TS
> concept and thus immutable from Beast's perspective. Therefore
> beast::http::basic_dynamic_body cannot work with std::string and
> beast::http::string_body becomes necessary . I will likely add
> beast::http::basic_string_body to allow the allocator to be
> customized.
>
>

As a user I'd prefer not to have string_body as a distinct type too.
Same for string_view_body. Both are tightly bounded to distinct types.

Instead of having more and more body types tightly bounded to distinct
types i would prefer less body types loosely bounded to concepts.

So with a concept of "character sequence" we could introduce a
"sequence_body" working with models like std::string, std::string_view,
boost::string_ref, std::vector<char>, etc.

And with a concept of "character stream" we could introduce a
"stream_body" working with models like std::[o|i]stringstream,
std::[o|i]fstream, boost::iostreams::stream, etc.

These two new body types could replace string_body, string_view_body,
const_body (from example/common) and mutable_body (from example/common).

So we end up with less body types and less redundance, but much more
flexibility and testability.

Sample code for using these new body types below.
What do other participants think about this concept based body design?

Thanks,
Mike...

#include <beast/core.hpp>
#include <beast/http.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include "sequence_body.hpp"
#include "stream_body.hpp"

inline constexpr auto host = "httpbin.org";

void sequence_body_demo(boost::asio::ip::tcp::socket& socket,
beast::flat_buffer& buffer)
{
     using string_view_body = beast::http::sequence_body<std::string_view>;
     using string_body = beast::http::sequence_body<std::string>;

     beast::http::request<string_view_body> request;
     request.method(beast::http::verb::post);
     request.target("/post");
     request.set(beast::http::field::host, host);
     request.set(beast::http::field::content_length, 3);
     request.body = "foo";
     beast::http::write(socket, request);

     beast::http::response<string_body> response;
     beast::http::read(socket, buffer, response);
     std::cout << response.body << std::endl;
}

void stream_body_demo(boost::asio::ip::tcp::socket& socket,
beast::flat_buffer& buffer)
{
     using ifstream_body = beast::http::stream_body<std::ifstream>;
     using osstream_body = beast::http::stream_body<std::ostringstream>;

     beast::http::request<ifstream_body> request;
     request.method(beast::http::verb::post);
     request.target("/post");
     request.set(beast::http::field::host, host);
     request.set(beast::http::field::content_length, 3); // chunked does
not work, httpbin needs content_length
     request.body.open("foo.txt");
     beast::http::write(socket, request);

     beast::http::response<osstream_body> response;
     beast::http::read(socket, buffer, response);
     std::cout << response.body.str() << std::endl;
}

int main()
{
     try
     {
         boost::asio::io_service service;
         boost::asio::ip::tcp::socket socket {service};
         boost::asio::ip::tcp::resolver resolver {service};
         boost::asio::connect(socket, resolver.resolve({host, "http"}));
         beast::flat_buffer buffer;

         sequence_body_demo(socket, buffer);
         stream_body_demo(socket, buffer);
     }
     catch (std::exception const& exception)
     {
         std::cerr << "error: " << exception.what() << std::endl;
     }
     return 0;
}

==>

{
   "args": {},
   "data": "foo",
   "files": {},
   "form": {},
   "headers": {
     "Connection": "close",
     "Content-Length": "3",
     "Host": "httpbin.org"
   },
   "json": null,
   "origin": "46.59.255.80",
   "url": "http://httpbin.org/post"
}

{
   "args": {},
   "data": "foo",
   "files": {},
   "form": {},
   "headers": {
     "Connection": "close",
     "Content-Length": "3",
     "Host": "httpbin.org"
   },
   "json": null,
   "origin": "46.59.255.80",
   "url": "http://httpbin.org/post"
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk