libnghttp2_asio: High level HTTP/2 C++ library¶

libnghttp2_asio is C++ library built on top of libnghttp2 and provides high level abstraction API to build HTTP/2 applications. It depends on Boost::ASIO library and OpenSSL. Currently libnghttp2_asio provides server and client side API.

libnghttp2_asio is not built by default. Use --enable-asio-lib configure flag to build libnghttp2_asio. The required Boost libraries are:

Boost::Asio

Boost::System

Boost::Thread

We have 3 header files for this library:

asio_http2.h is included from the other two files.

To build a program with libnghttp2_asio, link to the following libraries:

- lnghttp2_asio - lboost_system

If boost::asio::ssl is used in application code, OpenSSL is also required in link line:

- lnghttp2_asio - lboost_system - lssl - lcrypto

Server API¶ To use server API, first include following header file: #include <nghttp2/asio_http2_server.h> Also take a look at that header file asio_http2_server.h. Server API is designed to build HTTP/2 server very easily to utilize C++11 anonymous function and closure. The bare minimum example of HTTP/2 server looks like this: using namespace nghttp2 :: asio_http2 ; using namespace nghttp2 :: asio_http2 :: server ; int main ( int argc , char * argv []) { boost :: system :: error_code ec ; http2 server ; server . handle ( "/" , []( const request & req , const response & res ) { res . write_head ( 200 ); res . end ( "hello, world

" ); }); if ( server . listen_and_serve ( ec , "localhost" , "3000" )) { std :: cerr << "error: " << ec . message () << std :: endl ; } } First we instantiate nghttp2::asio_http2::server::http2 object. nghttp2::asio_http2::server::http2::handle function registers pattern and its handler function. In this example, we register "/" as pattern, which matches all requests. Then call nghttp2::asio_http2::server::http2::listen_and_serve function with address and port to listen to. The req and res represent HTTP request and response respectively. nghttp2::asio_http2_::server::response::write_head constructs HTTP response header fields. The first argument is HTTP status code, in the above example, which is 200. The second argument, which is omitted in the above example, is additional header fields to send. nghttp2::asio_http2::server::response::end sends response body. In the above example, we send string "hello, world". The life time of req and res object ends after the callback set by nghttp2::asio_http2::server::response::on_close function. Application must not use those objects after this call. Serving static files and enabling SSL/TLS¶ In this example, we serve a couple of static files and also enable SSL/TLS. #include <nghttp2/asio_http2_server.h> using namespace nghttp2 :: asio_http2 ; using namespace nghttp2 :: asio_http2 :: server ; int main ( int argc , char * argv []) { boost :: system :: error_code ec ; boost :: asio :: ssl :: context tls ( boost :: asio :: ssl :: context :: sslv23 ); tls . use_private_key_file ( "server.key" , boost :: asio :: ssl :: context :: pem ); tls . use_certificate_chain_file ( "server.crt" ); configure_tls_context_easy ( ec , tls ); http2 server ; server . handle ( "/index.html" , []( const request & req , const response & res ) { res . write_head ( 200 ); res . end ( file_generator ( "index.html" )); }); if ( server . listen_and_serve ( ec , tls , "localhost" , "3000" )) { std :: cerr << "error: " << ec . message () << std :: endl ; } } We first create boost::asio::ssl::context object and set path to private key file and certificate file. nghttp2::asio_http2::server::configure_tls_context_easy function configures SSL/TLS context object for HTTP/2 server use, including NPN callbacks. In the above example, if request path is "/index.html", we serve index.html file in the current working directory. nghttp2::asio_http2::server::response::end has overload to take function of type nghttp2::asio_http2::generator_cb and application pass its implementation to generate response body. For the convenience, libnghttp2_asio library provides nghttp2::asio_http2::file_generator function to generate function to server static file. If other resource is requested, server automatically responds with 404 status code. Server push¶ Server push is also supported. #include <nghttp2/asio_http2_server.h> using namespace nghttp2 :: asio_http2 ; using namespace nghttp2 :: asio_http2 :: server ; int main ( int argc , char * argv []) { boost :: system :: error_code ec ; boost :: asio :: ssl :: context tls ( boost :: asio :: ssl :: context :: sslv23 ); tls . use_private_key_file ( "server.key" , boost :: asio :: ssl :: context :: pem ); tls . use_certificate_chain_file ( "server.crt" ); configure_tls_context_easy ( ec , tls ); http2 server ; std :: string style_css = "h1 { color: green; }" ; server . handle ( "/" , [ & style_css ]( const request & req , const response & res ) { boost :: system :: error_code ec ; auto push = res . push ( ec , "GET" , "/style.css" ); push -> write_head ( 200 ); push -> end ( style_css ); res . write_head ( 200 ); res . end ( R " ( <!DOCTYPE html><html lang="en"> <title>HTTP/2 FTW</title><body> <link href="/style.css" rel="stylesheet" type="text/css"> <h1>This should be green</h1> </body></html> ) " ); }); server . handle ( "/style.css" , [ & style_css ]( const request & req , const response & res ) { res . write_head ( 200 ); res . end ( style_css ); }); if ( server . listen_and_serve ( ec , tls , "localhost" , "3000" )) { std :: cerr << "error: " << ec . message () << std :: endl ; } } When client requested any resource other than "/style.css", we push "/style.css". To push resource, call nghttp2::asio_http2::server::response::push function with desired method and path. It returns another response object and use its functions to send push response. Enable multi-threading¶ Enabling multi-threading is very easy. Just call nghttp2::asio_http2::server::http2::num_threads function with the desired number of threads: http2 server ; // Use 4 native threads server . num_threads ( 4 );