tizen 2.4 release
[external/nghttp2.git] / doc / sources / libnghttp2_asio.rst
1 libnghttp2_asio: High level HTTP/2 C++ library
2 ==============================================
3
4 libnghttp2_asio is C++ library built on top of libnghttp2 and provides
5 high level abstraction API to build HTTP/2 applications.  It depends
6 on Boost::ASIO library and OpenSSL.  Currently libnghttp2_asio
7 provides server side API.
8
9 libnghttp2_asio is not built by default.  Use ``--enable-asio-lib``
10 configure flag to build libnghttp2_asio.  The required Boost libraries
11 are:
12
13 * Boost::Asio
14 * Boost::System
15 * Boost::Thread
16
17 To use libnghttp2_asio, first include following header file:
18
19 .. code-block:: cpp
20
21     #include <nghttp2/asio_http2.h>
22
23 Also take a look at that header file :doc:`asio_http2.h`.
24
25 Server API
26 ----------
27
28 Server API is designed to build HTTP/2 server very easily to utilize
29 C++11 anonymous function and closure.  The bare minimum example of
30 HTTP/2 server looks like this:
31
32 .. code-block:: cpp
33
34     #include <nghttp2/asio_http2.h>
35
36     using namespace nghttp2::asio_http2;
37     using namespace nghttp2::asio_http2::server;
38
39     int main(int argc, char *argv[]) {
40       http2 server;
41
42       server.listen("*", 3000, [](const std::shared_ptr<request> &req,
43                                   const std::shared_ptr<response> &res) {
44         res->write_head(200);
45         res->end("hello, world");
46       });
47     }
48
49 First we instantiate ``nghttp2::asio_http2::server::http2`` object.
50 Then call ``nghttp2::asio_http2::server::http2::listen`` function with
51 address and port to listen to and callback function, namely "request
52 callback", invoked when request arrives.
53
54 The ``req`` and ``res`` represent HTTP request and response
55 respectively.  ``nghttp2::asio_http2_::server::response::write_head``
56 constructs HTTP response header fields.  The first argument is HTTP
57 status code, in the above example, which is 200.  The second argument,
58 which is omitted in the above example, is additional header fields to
59 send.
60
61 ``nghttp2::asio_http2::server::response::end`` sends responde body.
62 In the above example, we send string "hello, world".
63
64 Serving static files and enabling SSL/TLS
65 +++++++++++++++++++++++++++++++++++++++++
66
67 In this example, we serve a couple of static files and also enable
68 SSL/TLS.
69
70 .. code-block:: cpp
71
72     #include <nghttp2/asio_http2.h>
73
74     using namespace nghttp2::asio_http2;
75     using namespace nghttp2::asio_http2::server;
76
77     int main(int argc, char *argv[]) {
78       http2 server;
79
80       server.tls("server.key", "server.crt");
81
82       server.listen("*", 3000, [](const std::shared_ptr<request> &req,
83                                   const std::shared_ptr<response> &res) {
84         if (req->path() == "/" || req->path() == "/index.html") {
85           res->write_head(200);
86           res->end(file_reader("index.html"));
87         } else {
88           res->write_head(404);
89           res->end("<html><head><title>404</title></head>"
90                    "<body>404 Not Found</body></html>");
91         }
92       });
93     }
94
95 Specifying path to private key file and certificate file in
96 ``nghttp2::asio_http2::server::http2::tls`` will enable SSL/TLS.  Both
97 files must be in PEM format.
98
99 In the above example, if request path is either "/" or "/index.html",
100 we serve index.html file in the current working directory.
101 ``nghttp2::asio_http2::server::response::end`` has overload to take
102 function of type ``nghttp2::asio_http2::read_cb`` and application pass
103 its implementation to generate response body.  For the convenience,
104 libnghttp2_asio library provides ``nghttp2::asio_http2::file_reader``
105 function to generate function to server static file.
106
107 Server push
108 +++++++++++
109
110 Server push is also supported.
111
112 .. code-block:: cpp
113
114     #include <nghttp2/asio_http2.h>
115
116     using namespace nghttp2::asio_http2;
117     using namespace nghttp2::asio_http2::server;
118
119     int main(int argc, char *argv[]) {
120       http2 server;
121
122       server.tls("server.key", "server.crt");
123
124       server.listen("*", 3000, [](const std::shared_ptr<request> &req,
125                                   const std::shared_ptr<response> &res) {
126         if (req->path() == "/") {
127           req->push("GET", "/my.css");
128
129           res->write_head(200);
130           res->end(file_reader("index.html"));
131
132           return;
133         }
134
135         if (req->path() == "/my.css") {
136           res->write_head(200);
137           res->end(file_reader("my.css"));
138
139           return;
140         }
141
142         res->write_head(404);
143         res->end("<html><head><title>404</title></head>"
144                  "<body>404 Not Found</body></html>");
145       });
146     }
147
148 When client requested "/", we push "/my.css".  To push resource, call
149 ``nghttp2::asio_http2::server::request::push`` function with desired
150 method and path.  Later, the callback will be called with the pushed
151 resource "/my.css".
152
153 Enable multi-threading
154 ++++++++++++++++++++++
155
156 Enabling multi-threading is very easy.  Just call
157 ``nghttp2::asio_http2::server::http2::num_threads`` function with the
158 desired number of threads:
159
160 .. code-block:: cpp
161
162     http2 server;
163
164     // Use 4 native threads
165     server.num_threads(4);
166
167 Run blocking tasks in background thread
168 +++++++++++++++++++++++++++++++++++++++
169
170 The request callback is called in the same thread where HTTP request
171 is handled.  And many connections shares the same thread, we cannot
172 directly run blocking tasks in request callback.
173
174 To run blocking tasks, use
175 ``nghttp2::asio_http2::server::request::run_task``.  The passed
176 callback will be executed in the different thread from the thread
177 where request callback was executed.  So application can perform
178 blocking task there.  The example follows:
179
180 .. code-block:: cpp
181
182     #include <unistd.h>
183     #include <nghttp2/asio_http2.h>
184
185     using namespace nghttp2::asio_http2;
186     using namespace nghttp2::asio_http2::server;
187
188     int main(int argc, char *argv[]) {
189       http2 server;
190
191       server.num_concurrent_tasks(16);
192
193       server.listen("*", 3000, [](const std::shared_ptr<request> &req,
194                                   const std::shared_ptr<response> &res) {
195         req->run_task([res](channel &channel) {
196           // executed in different thread than the thread where
197           // request callback was executed.
198
199           // using res directly here is not safe.  Capturing it by
200           // value is safe because it is std::shared_ptr.
201
202           sleep(1);
203
204           channel.post([res]() {
205             // executed in the same thread where request callback
206             // was executed.
207             res->write_head(200);
208             res->end("hello, world");
209           });
210         });
211       });
212     }
213
214 First we set the number of background threads which run tasks.  By
215 default it is set to 1.  In this example, we set it to 16, so at most
216 16 tasks can be executed concurrently without blocking handling new
217 requests.
218
219 We call ``req->run_task()`` to execute task in background thread.  In
220 the passed callback, we just simply sleeps 1 second.  After sleep is
221 over, we schedule another callback to send response to the client.
222 Since the callback passed to ``req->run_task()`` is executed in the
223 different thread from the thread where request callback is called,
224 using ``req`` or ``res`` object directly there may cause undefined
225 behaviour.  To avoid this issue, we can use
226 ``nghttp2::asio_http2::channel::post`` by supplying a callback which
227 in turn get called in the same thread where request callback was
228 called.