
I'm out of time to actually try the library, so will give my review based on just the study of the documentation/mailing list comments.
1. Should Boost.Http be accepted into Boost? Please state all conditions for acceptance explicitly.
No, sorry.
2. What is your evaluation of the design? 3. What is your evaluation of the implementation? 4. What is your evaluation of the documentation? 5. What is your evaluation of the potential usefulness of the library?
From what I can tell, the design is an ambitious attempt to be all
The documentation did not allow me to tell if this is a weak library, or a good library that is being marketed badly. It contains a single example which is very long and off-putting. The initial page gives a list of features, and the design rationale repeats them, but not how to use any of them. The first example in the documentation should be no more than 10 lines. Then there must be examples that show: SSL (using a self-signed certificate), a file server, a routing application with 2-3 routers doing distinct things and an example of streaming data. things to all people. IMHO this is a fatal mistake. Naming and Scope: It should be called Boost.HttpServer; and then there should be another library called Boost.HttpClient. Reasons: 1. They will share very little public API code 2. The majority of projects that need an http server will not also need an http client; the huge majority of projects that need an http client will not need an http server. (The 1% that need both can just include both libraries.) 3. There is not actually a great amount of implementation code they share. 4. Http is a protocol. Libraries shouldn't map to protocols, they should map to the work people need to do. API Level: What C++ badly needs is a high-level, easy to use http server library. It needs a high-level http client library even more badly. The proposed library looks like some building blocks towards this. I suggest it either stay as a github project that an Boost.HttpServer can build upon, or be merged into asio as an extension. Here is the kind of http server api I was hoping to see up for review (this is the short motivating example I expected to see as the first thing in the tutorial): (...moved to [1]) My opinion on some other topics the review has brought up: Header-only: Yes, important. Pre-C++11 support: No need. C++11 is more pleasant, and building in reliance on lambda or any other C++11 feature is acceptable if it makes the design nicer. I could even accept it being C++14-only if there was a good reason. Asio Integration: No need. I have used boost::asio on some projects. I do not enjoy using it, it is easy to get things wrong, code tends to become long and complicated and/or it is under-documented. (While I wait for my ideal C++ http-server I will now use posix socket's C functions directly. And while waiting for my ideal C++ http-client implementation, I am using curl.) In other words, if it is built on top of asio I want that as an implementation detail I don't have to care about. Http/2: Not essential at this stage. However it has to be clear that the design and API supports moving to it transparently. As that may not be trivial, I think a library offered for review does have to show support for http/2. Streaming: I would like to see examples of sending a chunked response, and of sending a streaming (SSE or old-fashioned comet) response that never closes. This may reveal bugs or design flaws. Routing: A built-in router should be part of the version for review. It should be a distinct component so that alternatives can be used, but `boost::httpserver::server` should be using a "pleases-most-people-most-of-the-time" implementation. If routing is not included, everyone will end up rolling their own, and that is bad. Benchmarks: I would like to see CPU and memory usage benchmarks; ideally on reference hardware such as an Amazon EC2 instance. Realistic examples such as: a simple file server, a file-server that is doing substitution/modification of the files being read, and a chat server. This is because artificial benchmarks often encourage making the design harder to use for the sake of a few microseconds. I'd rather have a server, doing real work, that can support 499 clients/second than one that can support 500 clients/second but requires me to write twice as much code.
6. Did you try to use the library? With what compiler? Did you have any problems?
No.
7. How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
Maybe 10 hours reading the documentation, following the discussion, and forming my thoughts here. I only glanced at the code on github (mainly in the hope of finding more examples or documentation).
8. Are you knowledgeable about the problem domain?
Reasonably so. I've written socket clients and socket servers in C++, C#, PHP and Node.js. I have used asio, and looked at various C++ http libraries (usually ending up rejecting them all). I have a lot of experience with LAMP stacks, and with http scaling issues. For an http server API my favourite design is node.js's http module (though it lacks routing). For an http client I like the power and simplicity of PHP's file_get_contents(). Darren -- Darren Cook, Software Researcher/Developer My new book: Data Push Apps with HTML5 SSE Published by O'Reilly: (ask me for a discount code!) http://shop.oreilly.com/product/0636920030928.do Also on Amazon and at all good booksellers! [1]: #include <boost/http_server.h> using namespace boost::httpserver; int main(){ server server; server.add_handler([](request request,response response){ response.send("Hello client"); }); server.run(); return 0; //Never reach here } The constructor defaults options, in this case defaulting to http/1.1, listening on 127.0.0.1, listening on port 80, and no SSL. [2] add_handler() with just one parameter takes a function that is the default handler. With two parameters, the first is a router pattern match, and the second is the function to handle it. The function takes request and response objects. The request tells me the URL and the headers and the cookies. The response is what I talk with. Beyond send(), there are functions to send cookies and other headers. It defaults to status code 200 if one not given before the first send(). server.run() is (conceptually) implemented as: server.bind(); server.listen(); They throw exceptions for errors. server.listen() is an infinite loop. By default it maintains a thread pool, and each request runs on a dedicated thread. [3] [2]: For implementation I think I'd go with separate classes for each of the combinations of SSL/no-SSL and http/1.0, http/1.1 and http/2, and boost::httpserver::server would just be a typedef. (A scaled-up web server would usually put the global IP and SSL certificate on the load balancer, not on the individual clients.) An SSL version might look like: http11_SSL_server server; server.options['key'] = "/path/to/my-key.pem"; server.options['cert'] = "/path/to/my-cert.pem"; server.add_handler(...); server.run(); I prefer using an std::map<std::string, std::string> options, as it can be passed around to helper classes, i.e. compared to this: server.key = "/path/to/my-key.pem"; server.cert = "/path/to/my-cert.pem"; [3]: I would have the request handler object as a templated parameter on the server. Then it can be replaced with one using fibres, external cgi processes, etc. However it shares the same options map as the server object.