So why are you forcing end users to drag in ASIO?
Beast will be part of Boost, whose distributions include Asio. To use serializer or basic_parser, the header
must be included, which is a pretty self-contained file. This is a temporary situation until Boost.Asio is updated to N4588.
If the dependency is so limited, then remove it entirely and split Beast into non-ASIO and ASIO parts. Most of Beast is a structured data utility library focused on HTTP. If you made the parser capable of discontiguous input (iterator input) and it could handle more gracefully partial/incomplete input than it currently does, I would think it pretty much ideal and a superb foundation for everything HTTP related for all possible end users.
Very little in your library has, or ought to have, anything to do with i/o. .. Stop thinking in terms of i/o. HTTP is just structured data. So treat it as such. Parse as structured data, generate as structured data.
Is my understanding correct that you say Beast should not provide functions to send and receiving HTTP messages using Asio streams?
Absolutely correct. A highly reusable and flexible Beast would have a design where knowledge of ASIO is unimportant. A second, separate library can then combine the generic, reusable Beast stuff with ASIO to implement lots of useful things like WebSockets etc. Separate the concerns, decouple implementation. I would imagine you have three design choices there: 1. Stop short of i/o, and instead provide source iterator pairs from which ASIO (or anything else) can construct a gather buffer sequence via boost::make_iterator_range() which is how you tell ASIO to borrow instead of copy a gather buffer sequence. It is on the end user to pump any state machine or sequence or reactor. 2. Provide a "tick function" for any reactor in use by the user to pump HTTP. Study the Qt networking framework as a comparator to ASIO (it's pretty similar). 3. Provide a generic method of wrapping some arbitrary third party networking implementation, so Beast provides async_read(), async_write() etc as now, the HTTP layer does its thing, and the underlying i/o implementation gets called eventually. The classic - if ugly - implementation of this is OpenSSL via its BIO mechanism. You can do far better in C++ 11. Me, personally speaking, I would favour option 1. It's the least work, most flexible for end users with whatever weird i/o transport they might be using, and seems most in keeping with the overall library design philosophy of minimal but powerful abstraction. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/