Boost logo

Boost :

Subject: Re: [boost] New Lib "Beast", HTTP + WebSocket protocols
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2016-04-24 17:34:31

On Sun, Apr 24, 2016 at 3:33 PM, Vinícius dos Santos Oliveira
<vini.ipsmaker_at_[hidden]> wrote:
> I wish you could put more details in the documentation, so I can understand
> Beast better without delving into the code.

Agreed. The HTTP side can definitely use more documentation. Since the
announcement I added a new page which explains things step by step:

> like Bjorn already stated, nice library.

Thanks, it is appreciated!

> Could you please write an example of how do you imagine the ideal
> server-side API?

Well, being role-agnostic means the same functions are used by both
clients and servers. The only meaningful difference is that a server
will receive request objects and send response objects instead of the
other way around. The message class template distinguishes requests
and responses using a bool "isRequest" template argument. These
statements each declare a response:

    http::message<false, http::string_body> resp;
    http::response<http::string_body> resp2;

Both of these declarations are identical, http::response is merely a
type alias for http::message with the bool "isRequest" set to true.

The same functions are used by both clients and servers to read and
write messages:

    // synchronous
    http::write(sock, resp);

    // asynchronous
    void handle_write(boost::system::error_code);
    http::async_write(sock, resp,
        std::bind(&handle_write, std::placeholders::_1));

Beast comes with an example program that implements a basic web
server, capable of serving simple HTML, in both synchronous and
asynchronous forms:

> may be useful to add client-side only useful functions where we can
> have specialized get or post methods.

These definitely sound like useful operations, and they should be
available at some interface level. But its not clear that they they
are sufficiently general purpose as to merit inclusion in a library
that tries to satisfy everyone. No matter how specialized the get or
post method there still needs to be a way to package the message up in
a first-class type and send or receive it; Beast provides the means to
do that.

>> Thursday I started on a header-only parser,
> I wasn't aware of this effort before.

Its a minor effort, likely not worthy of fanfare.

> I took a look now that you mentioned. From what I've seen, I assume that
> this parser has a SAX-like interface where you interact through callbacks.

I'm writing something that functions very similarly in style to the
nodejs-http-parser, but updated for C++. The goal here is to eliminate
a blemish on Beast, that it is not completely header-only. It inherits
the zero-memory / zero-copy design of nodejs-http-parse to retain as
much of its performance as possible (although, it does away with
architecture-specific branch prediction hints). Some of the design
improvements I'm making:

* Users derive from the parser base class using CRTP (Curiously
Recurring Template Pattern)
* Callbacks are optional, detected through SFINAE
* Callbacks are made to the derived class
* The callbacks are transparent to the compiler (i.e. no function
pointers), allowing inlining
* No macros or dependence on preprocessor directives
* No dependencies except for boost::string_ref; easily reused in other projects
* Random HTTP-message generator for fuzzing

> The Boost.Http parser that will be developed within this summer will be a
> pull parser. It has a less intrusive design and can be used to build parser
> with SAX-like interfaces or DOM-like interfaces. It should be useful enough
> to also be used as is (i.e. without wrapping in another interface).

Beast doesn't try to offer a universal or flexible parser, it just
offers a parser that gets users reading messages right out of the box,
and is sufficiently robust and performant as to make it a competitive
choice for implementing production-class servers.

Beast's HTTP message reading implementation is general purpose,
callers can provide their own Parser template argument that meets the
type requirements (*), permitting alternate implementation strategies.
For example, keeping only the headers you care about. Or using a
perfect hash function to decode the field name to an enum. This works
hand in hand with customizing the Headers parameter in the message
class template argument.

(*) planned feature

> It should also be easy to expose iterators using this parser and allow us to
> reuse all STL algorithms.

Since the whole thing is now templated it might be practical to revise
the interface to accept a Boost.Range of chars and work with iterators
in the fashion you described. That could be the subject of a future

Boost list run by bdawes at, gregod at, cpdaniel at, john at