1nghttp2 - HTTP/2 C Library 2========================== 3 4This is an implementation of the Hypertext Transfer Protocol version 2 5in C. 6 7The framing layer of HTTP/2 is implemented as a reusable C library. 8On top of that, we have implemented an HTTP/2 client, server and 9proxy. We have also developed load test and benchmarking tools for 10HTTP/2. 11 12An HPACK encoder and decoder are available as a public API. 13 14An experimental high level C++ library is also available. 15 16We have Python bindings of this library, but we do not have full 17code coverage yet. 18 19Development Status 20------------------ 21 22We have implemented `RFC 7540 <https://tools.ietf.org/html/rfc7540>`_ 23HTTP/2 and `RFC 7541 <https://tools.ietf.org/html/rfc7541>`_ HPACK - 24Header Compression for HTTP/2 25 26The nghttp2 code base was forked from the spdylay 27(https://github.com/tatsuhiro-t/spdylay) project. 28 29Public Test Server 30------------------ 31 32The following endpoints are available to try out our nghttp2 33implementation. 34 35* https://nghttp2.org/ (TLS + ALPN/NPN) 36 37 This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and 38 ``http/1.1`` via ALPN/NPN and requires TLSv1.2 for HTTP/2 39 connection. 40 41* http://nghttp2.org/ (HTTP Upgrade and HTTP/2 Direct) 42 43 ``h2c`` and ``http/1.1``. 44 45Requirements 46------------ 47 48The following package is required to build the libnghttp2 library: 49 50* pkg-config >= 0.20 51 52To build and run the unit test programs, the following package is 53required: 54 55* cunit >= 2.1 56 57To build the documentation, you need to install: 58 59* sphinx (http://sphinx-doc.org/) 60 61If you need libnghttp2 (C library) only, then the above packages are 62all you need. Use ``--enable-lib-only`` to ensure that only 63libnghttp2 is built. This avoids potential build error related to 64building bundled applications. 65 66To build and run the application programs (``nghttp``, ``nghttpd``, 67``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages 68are required: 69 70* OpenSSL >= 1.0.1 71* libev >= 4.11 72* zlib >= 1.2.3 73* libc-ares >= 1.7.5 74 75ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015). 76LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more 77features than LibreSSL at the time of this writing. 78 79To enable ``-a`` option (getting linked assets from the downloaded 80resource) in ``nghttp``, the following package is required: 81 82* libxml2 >= 2.6.26 83 84To enable systemd support in nghttpx, the following package is 85required: 86 87* libsystemd-dev >= 209 88 89The HPACK tools require the following package: 90 91* jansson >= 2.5 92 93To build sources under the examples directory, libevent is required: 94 95* libevent-openssl >= 2.0.8 96 97To mitigate heap fragmentation in long running server programs 98(``nghttpd`` and ``nghttpx``), jemalloc is recommended: 99 100* jemalloc 101 102 .. note:: 103 104 Alpine Linux currently does not support malloc replacement 105 due to musl limitations. See details in issue `#762 <https://github.com/nghttp2/nghttp2/issues/762>`_. 106 107libnghttp2_asio C++ library requires the following packages: 108 109* libboost-dev >= 1.54.0 110* libboost-thread-dev >= 1.54.0 111 112The Python bindings require the following packages: 113 114* cython >= 0.19 115* python >= 3.8 116* python-setuptools 117 118If you are using Ubuntu 16.04 LTS (Xenial Xerus) or Debian 8 (jessie) 119and above, run the following to install the required packages: 120 121.. code-block:: text 122 123 sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \ 124 zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \ 125 libc-ares-dev libjemalloc-dev libsystemd-dev \ 126 cython python3-dev python-setuptools 127 128To enable mruby support for nghttpx, `mruby 129<https://github.com/mruby/mruby>`_ is required. We need to build 130mruby with C++ ABI explicitly turned on, and probably need other 131mrgems, mruby is manged by git submodule under third-party/mruby 132directory. Currently, mruby support for nghttpx is disabled by 133default. To enable mruby support, use ``--with-mruby`` configure 134option. Note that at the time of this writing, libmruby-dev and mruby 135packages in Debian/Ubuntu are not usable for nghttp2, since they do 136not enable C++ ABI. To build mruby, the following packages are 137required: 138 139* ruby 140* bison 141 142nghttpx supports `neverbleed <https://github.com/h2o/neverbleed>`_, 143privilege separation engine for OpenSSL / LibreSSL. In short, it 144minimizes the risk of private key leakage when serious bug like 145Heartbleed is exploited. The neverbleed is disabled by default. To 146enable it, use ``--with-neverbleed`` configure option. 147 148Compiling libnghttp2 C source code requires a C99 compiler. gcc 4.8 149is known to be adequate. In order to compile the C++ source code, gcc 150>= 6.0 or clang >= 6.0 is required. C++ source code requires C++14 151language features. 152 153.. note:: 154 155 To enable mruby support in nghttpx, and use ``--with-mruby`` 156 configure option. 157 158.. note:: 159 160 Mac OS X users may need the ``--disable-threads`` configure option to 161 disable multi-threading in nghttpd, nghttpx and h2load to prevent 162 them from crashing. A patch is welcome to make multi threading work 163 on Mac OS X platform. 164 165.. note:: 166 167 To compile the associated applications (nghttp, nghttpd, nghttpx 168 and h2load), you must use the ``--enable-app`` configure option and 169 ensure that the specified requirements above are met. Normally, 170 configure script checks required dependencies to build these 171 applications, and enable ``--enable-app`` automatically, so you 172 don't have to use it explicitly. But if you found that 173 applications were not built, then using ``--enable-app`` may find 174 that cause, such as the missing dependency. 175 176.. note:: 177 178 In order to detect third party libraries, pkg-config is used 179 (however we don't use pkg-config for some libraries (e.g., libev)). 180 By default, pkg-config searches ``*.pc`` file in the standard 181 locations (e.g., /usr/lib/pkgconfig). If it is necessary to use 182 ``*.pc`` file in the custom location, specify paths to 183 ``PKG_CONFIG_PATH`` environment variable, and pass it to configure 184 script, like so: 185 186 .. code-block:: text 187 188 $ ./configure PKG_CONFIG_PATH=/path/to/pkgconfig 189 190 For pkg-config managed libraries, ``*_CFLAG`` and ``*_LIBS`` 191 environment variables are defined (e.g., ``OPENSSL_CFLAGS``, 192 ``OPENSSL_LIBS``). Specifying non-empty string to these variables 193 completely overrides pkg-config. In other words, if they are 194 specified, pkg-config is not used for detection, and user is 195 responsible to specify the correct values to these variables. For 196 complete list of these variables, run ``./configure -h``. 197 198Building nghttp2 from release tar archive 199----------------------------------------- 200 201The nghttp2 project regularly releases tar archives which includes 202nghttp2 source code, and generated build files. They can be 203downloaded from `Releases 204<https://github.com/nghttp2/nghttp2/releases>`_ page. 205 206Building nghttp2 from git requires autotools development packages. 207Building from tar archives does not require them, and thus it is much 208easier. The usual build step is as follows: 209 210.. code-block:: text 211 212 $ tar xf nghttp2-X.Y.Z.tar.bz2 213 $ cd nghttp2-X.Y.Z 214 $ ./configure 215 $ make 216 217Building from git 218----------------- 219 220Building from git is easy, but please be sure that at least autoconf 2.68 is 221used: 222 223.. code-block:: text 224 225 $ git submodule update --init 226 $ autoreconf -i 227 $ automake 228 $ autoconf 229 $ ./configure 230 $ make 231 232Notes for building on Windows (MSVC) 233------------------------------------ 234 235The easiest way to build native Windows nghttp2 dll is use `cmake 236<https://cmake.org/>`_. The free version of `Visual C++ Build Tools 237<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works 238fine. 239 2401. Install cmake for windows 2412. Open "Visual C++ ... Native Build Tool Command Prompt", and inside 242 nghttp2 directly, run ``cmake``. 2433. Then run ``cmake --build`` to build library. 2444. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory. 245 246Note that the above steps most likely produce nghttp2 library only. 247No bundled applications are compiled. 248 249Notes for building on Windows (Mingw/Cygwin) 250-------------------------------------------- 251 252Under Mingw environment, you can only compile the library, it's 253``libnghttp2-X.dll`` and ``libnghttp2.a``. 254 255If you want to compile the applications(``h2load``, ``nghttp``, 256``nghttpx``, ``nghttpd``), you need to use the Cygwin environment. 257 258Under Cygwin environment, to compile the applications you need to 259compile and install the libev first. 260 261Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you 262not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not 263available. 264 265the sample command like this: 266 267.. code-block:: text 268 269 $ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib" 270 $ export CXXFLAGS=$CFLAGS 271 $ ./configure 272 $ make 273 274If you want to compile the applications under ``examples/``, you need 275to remove or rename the ``event.h`` from libev's installation, because 276it conflicts with libevent's installation. 277 278Notes for installation on Linux systems 279-------------------------------------------- 280After installing nghttp2 tool suite with ``make install`` one might experience a similar error: 281 282.. code-block:: text 283 284 nghttpx: error while loading shared libraries: libnghttp2.so.14: cannot open shared object file: No such file or directory 285 286This means that the tool is unable to locate the ``libnghttp2.so`` shared library. 287 288To update the shared library cache run ``sudo ldconfig``. 289 290Building the documentation 291-------------------------- 292 293.. note:: 294 295 Documentation is still incomplete. 296 297To build the documentation, run: 298 299.. code-block:: text 300 301 $ make html 302 303The documents will be generated under ``doc/manual/html/``. 304 305The generated documents will not be installed with ``make install``. 306 307The online documentation is available at 308https://nghttp2.org/documentation/ 309 310Unit tests 311---------- 312 313Unit tests are done by simply running ``make check``. 314 315Integration tests 316----------------- 317 318We have the integration tests for the nghttpx proxy server. The tests are 319written in the `Go programming language <http://golang.org/>`_ and uses 320its testing framework. We depend on the following libraries: 321 322* golang.org/x/net/http2 323* golang.org/x/net/websocket 324* https://github.com/tatsuhiro-t/go-nghttp2 325 326Go modules will download these dependencies automatically. 327 328To run the tests, run the following command under 329``integration-tests`` directory: 330 331.. code-block:: text 332 333 $ make it 334 335Inside the tests, we use port 3009 to run the test subject server. 336 337Migration from v0.7.15 or earlier 338--------------------------------- 339 340nghttp2 v1.0.0 introduced several backward incompatible changes. In 341this section, we describe these changes and how to migrate to v1.0.0. 342 343ALPN protocol ID is now ``h2`` and ``h2c`` 344++++++++++++++++++++++++++++++++++++++++++ 345 346Previously we announced ``h2-14`` and ``h2c-14``. v1.0.0 implements 347final protocol version, and we changed ALPN ID to ``h2`` and ``h2c``. 348The macros ``NGHTTP2_PROTO_VERSION_ID``, 349``NGHTTP2_PROTO_VERSION_ID_LEN``, 350``NGHTTP2_CLEARTEXT_PROTO_VERSION_ID``, and 351``NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN`` have been updated to 352reflect this change. 353 354Basically, existing applications do not have to do anything, just 355recompiling is enough for this change. 356 357Use word "client magic" where we use "client connection preface" 358++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 359 360We use "client connection preface" to mean first 24 bytes of client 361connection preface. This is technically not correct, since client 362connection preface is composed of 24 bytes client magic byte string 363followed by SETTINGS frame. For clarification, we call "client magic" 364for this 24 bytes byte string and updated API. 365 366* ``NGHTTP2_CLIENT_CONNECTION_PREFACE`` was replaced with 367 ``NGHTTP2_CLIENT_MAGIC``. 368* ``NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN`` was replaced with 369 ``NGHTTP2_CLIENT_MAGIC_LEN``. 370* ``NGHTTP2_BAD_PREFACE`` was renamed as ``NGHTTP2_BAD_CLIENT_MAGIC`` 371 372The already deprecated ``NGHTTP2_CLIENT_CONNECTION_HEADER`` and 373``NGHTTP2_CLIENT_CONNECTION_HEADER_LEN`` were removed. 374 375If application uses these macros, just replace old ones with new ones. 376Since v1.0.0, client magic is sent by library (see next subsection), 377so client application may just remove these macro use. 378 379Client magic is sent by library 380+++++++++++++++++++++++++++++++ 381 382Previously nghttp2 library did not send client magic, which is first 38324 bytes byte string of client connection preface, and client 384applications have to send it by themselves. Since v1.0.0, client 385magic is sent by library via first call of ``nghttp2_session_send()`` 386or ``nghttp2_session_mem_send()``. 387 388The client applications which send client magic must remove the 389relevant code. 390 391Remove HTTP Alternative Services (Alt-Svc) related code 392+++++++++++++++++++++++++++++++++++++++++++++++++++++++ 393 394Alt-Svc specification is not finalized yet. To make our API stable, 395we have decided to remove all Alt-Svc related API from nghttp2. 396 397* ``NGHTTP2_EXT_ALTSVC`` was removed. 398* ``nghttp2_ext_altsvc`` was removed. 399 400We have already removed the functionality of Alt-Svc in v0.7 series 401and they have been essentially noop. The application using these 402macro and struct, remove those lines. 403 404Use nghttp2_error in nghttp2_on_invalid_frame_recv_callback 405+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 406 407Previously ``nghttp2_on_invalid_frame_recv_cb_called`` took the 408``error_code``, defined in ``nghttp2_error_code``, as parameter. But 409they are not detailed enough to debug. Therefore, we decided to use 410more detailed ``nghttp2_error`` values instead. 411 412The application using this callback should update the callback 413signature. If it treats ``error_code`` as HTTP/2 error code, update 414the code so that it is treated as ``nghttp2_error``. 415 416Receive client magic by default 417+++++++++++++++++++++++++++++++ 418 419Previously nghttp2 did not process client magic (24 bytes byte 420string). To make it deal with it, we had to use 421``nghttp2_option_set_recv_client_preface()``. Since v1.0.0, nghttp2 422processes client magic by default and 423``nghttp2_option_set_recv_client_preface()`` was removed. 424 425Some application may want to disable this behaviour, so we added 426``nghttp2_option_set_no_recv_client_magic()`` to achieve this. 427 428The application using ``nghttp2_option_set_recv_client_preface()`` 429with nonzero value, just remove it. 430 431The application using ``nghttp2_option_set_recv_client_preface()`` 432with zero value or not using it must use 433``nghttp2_option_set_no_recv_client_magic()`` with nonzero value. 434 435Client, Server and Proxy programs 436--------------------------------- 437 438The ``src`` directory contains the HTTP/2 client, server and proxy programs. 439 440nghttp - client 441+++++++++++++++ 442 443``nghttp`` is a HTTP/2 client. It can connect to the HTTP/2 server 444with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension. 445 446It has verbose output mode for framing information. Here is sample 447output from ``nghttp`` client: 448 449.. code-block:: text 450 451 $ nghttp -nv https://nghttp2.org 452 [ 0.190] Connected 453 The negotiated protocol: h2 454 [ 0.212] recv SETTINGS frame <length=12, flags=0x00, stream_id=0> 455 (niv=2) 456 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 457 [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] 458 [ 0.212] send SETTINGS frame <length=12, flags=0x00, stream_id=0> 459 (niv=2) 460 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 461 [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] 462 [ 0.212] send SETTINGS frame <length=0, flags=0x01, stream_id=0> 463 ; ACK 464 (niv=0) 465 [ 0.212] send PRIORITY frame <length=5, flags=0x00, stream_id=3> 466 (dep_stream_id=0, weight=201, exclusive=0) 467 [ 0.212] send PRIORITY frame <length=5, flags=0x00, stream_id=5> 468 (dep_stream_id=0, weight=101, exclusive=0) 469 [ 0.212] send PRIORITY frame <length=5, flags=0x00, stream_id=7> 470 (dep_stream_id=0, weight=1, exclusive=0) 471 [ 0.212] send PRIORITY frame <length=5, flags=0x00, stream_id=9> 472 (dep_stream_id=7, weight=1, exclusive=0) 473 [ 0.212] send PRIORITY frame <length=5, flags=0x00, stream_id=11> 474 (dep_stream_id=3, weight=1, exclusive=0) 475 [ 0.212] send HEADERS frame <length=39, flags=0x25, stream_id=13> 476 ; END_STREAM | END_HEADERS | PRIORITY 477 (padlen=0, dep_stream_id=11, weight=16, exclusive=0) 478 ; Open new stream 479 :method: GET 480 :path: / 481 :scheme: https 482 :authority: nghttp2.org 483 accept: */* 484 accept-encoding: gzip, deflate 485 user-agent: nghttp2/1.0.1-DEV 486 [ 0.221] recv SETTINGS frame <length=0, flags=0x01, stream_id=0> 487 ; ACK 488 (niv=0) 489 [ 0.221] recv (stream_id=13) :method: GET 490 [ 0.221] recv (stream_id=13) :scheme: https 491 [ 0.221] recv (stream_id=13) :path: /stylesheets/screen.css 492 [ 0.221] recv (stream_id=13) :authority: nghttp2.org 493 [ 0.221] recv (stream_id=13) accept-encoding: gzip, deflate 494 [ 0.222] recv (stream_id=13) user-agent: nghttp2/1.0.1-DEV 495 [ 0.222] recv PUSH_PROMISE frame <length=50, flags=0x04, stream_id=13> 496 ; END_HEADERS 497 (padlen=0, promised_stream_id=2) 498 [ 0.222] recv (stream_id=13) :status: 200 499 [ 0.222] recv (stream_id=13) date: Thu, 21 May 2015 16:38:14 GMT 500 [ 0.222] recv (stream_id=13) content-type: text/html 501 [ 0.222] recv (stream_id=13) last-modified: Fri, 15 May 2015 15:38:06 GMT 502 [ 0.222] recv (stream_id=13) etag: W/"555612de-19f6" 503 [ 0.222] recv (stream_id=13) link: </stylesheets/screen.css>; rel=preload; as=stylesheet 504 [ 0.222] recv (stream_id=13) content-encoding: gzip 505 [ 0.222] recv (stream_id=13) server: nghttpx nghttp2/1.0.1-DEV 506 [ 0.222] recv (stream_id=13) via: 1.1 nghttpx 507 [ 0.222] recv (stream_id=13) strict-transport-security: max-age=31536000 508 [ 0.222] recv HEADERS frame <length=166, flags=0x04, stream_id=13> 509 ; END_HEADERS 510 (padlen=0) 511 ; First response header 512 [ 0.222] recv DATA frame <length=2601, flags=0x01, stream_id=13> 513 ; END_STREAM 514 [ 0.222] recv (stream_id=2) :status: 200 515 [ 0.222] recv (stream_id=2) date: Thu, 21 May 2015 16:38:14 GMT 516 [ 0.222] recv (stream_id=2) content-type: text/css 517 [ 0.222] recv (stream_id=2) last-modified: Fri, 15 May 2015 15:38:06 GMT 518 [ 0.222] recv (stream_id=2) etag: W/"555612de-9845" 519 [ 0.222] recv (stream_id=2) content-encoding: gzip 520 [ 0.222] recv (stream_id=2) server: nghttpx nghttp2/1.0.1-DEV 521 [ 0.222] recv (stream_id=2) via: 1.1 nghttpx 522 [ 0.222] recv (stream_id=2) strict-transport-security: max-age=31536000 523 [ 0.222] recv HEADERS frame <length=32, flags=0x04, stream_id=2> 524 ; END_HEADERS 525 (padlen=0) 526 ; First push response header 527 [ 0.228] recv DATA frame <length=8715, flags=0x01, stream_id=2> 528 ; END_STREAM 529 [ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0> 530 (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[]) 531 532The HTTP Upgrade is performed like so: 533 534.. code-block:: text 535 536 $ nghttp -nvu http://nghttp2.org 537 [ 0.011] Connected 538 [ 0.011] HTTP Upgrade request 539 GET / HTTP/1.1 540 Host: nghttp2.org 541 Connection: Upgrade, HTTP2-Settings 542 Upgrade: h2c 543 HTTP2-Settings: AAMAAABkAAQAAP__ 544 Accept: */* 545 User-Agent: nghttp2/1.0.1-DEV 546 547 548 [ 0.018] HTTP Upgrade response 549 HTTP/1.1 101 Switching Protocols 550 Connection: Upgrade 551 Upgrade: h2c 552 553 554 [ 0.018] HTTP Upgrade success 555 [ 0.018] recv SETTINGS frame <length=12, flags=0x00, stream_id=0> 556 (niv=2) 557 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 558 [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] 559 [ 0.018] send SETTINGS frame <length=12, flags=0x00, stream_id=0> 560 (niv=2) 561 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 562 [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] 563 [ 0.018] send SETTINGS frame <length=0, flags=0x01, stream_id=0> 564 ; ACK 565 (niv=0) 566 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=3> 567 (dep_stream_id=0, weight=201, exclusive=0) 568 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=5> 569 (dep_stream_id=0, weight=101, exclusive=0) 570 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=7> 571 (dep_stream_id=0, weight=1, exclusive=0) 572 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=9> 573 (dep_stream_id=7, weight=1, exclusive=0) 574 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=11> 575 (dep_stream_id=3, weight=1, exclusive=0) 576 [ 0.018] send PRIORITY frame <length=5, flags=0x00, stream_id=1> 577 (dep_stream_id=11, weight=16, exclusive=0) 578 [ 0.019] recv (stream_id=1) :method: GET 579 [ 0.019] recv (stream_id=1) :scheme: http 580 [ 0.019] recv (stream_id=1) :path: /stylesheets/screen.css 581 [ 0.019] recv (stream_id=1) host: nghttp2.org 582 [ 0.019] recv (stream_id=1) user-agent: nghttp2/1.0.1-DEV 583 [ 0.019] recv PUSH_PROMISE frame <length=49, flags=0x04, stream_id=1> 584 ; END_HEADERS 585 (padlen=0, promised_stream_id=2) 586 [ 0.019] recv (stream_id=1) :status: 200 587 [ 0.019] recv (stream_id=1) date: Thu, 21 May 2015 16:39:16 GMT 588 [ 0.019] recv (stream_id=1) content-type: text/html 589 [ 0.019] recv (stream_id=1) content-length: 6646 590 [ 0.019] recv (stream_id=1) last-modified: Fri, 15 May 2015 15:38:06 GMT 591 [ 0.019] recv (stream_id=1) etag: "555612de-19f6" 592 [ 0.019] recv (stream_id=1) link: </stylesheets/screen.css>; rel=preload; as=stylesheet 593 [ 0.019] recv (stream_id=1) accept-ranges: bytes 594 [ 0.019] recv (stream_id=1) server: nghttpx nghttp2/1.0.1-DEV 595 [ 0.019] recv (stream_id=1) via: 1.1 nghttpx 596 [ 0.019] recv HEADERS frame <length=157, flags=0x04, stream_id=1> 597 ; END_HEADERS 598 (padlen=0) 599 ; First response header 600 [ 0.019] recv DATA frame <length=6646, flags=0x01, stream_id=1> 601 ; END_STREAM 602 [ 0.019] recv (stream_id=2) :status: 200 603 [ 0.019] recv (stream_id=2) date: Thu, 21 May 2015 16:39:16 GMT 604 [ 0.019] recv (stream_id=2) content-type: text/css 605 [ 0.019] recv (stream_id=2) content-length: 38981 606 [ 0.019] recv (stream_id=2) last-modified: Fri, 15 May 2015 15:38:06 GMT 607 [ 0.019] recv (stream_id=2) etag: "555612de-9845" 608 [ 0.019] recv (stream_id=2) accept-ranges: bytes 609 [ 0.019] recv (stream_id=2) server: nghttpx nghttp2/1.0.1-DEV 610 [ 0.019] recv (stream_id=2) via: 1.1 nghttpx 611 [ 0.019] recv HEADERS frame <length=36, flags=0x04, stream_id=2> 612 ; END_HEADERS 613 (padlen=0) 614 ; First push response header 615 [ 0.026] recv DATA frame <length=16384, flags=0x00, stream_id=2> 616 [ 0.027] recv DATA frame <length=7952, flags=0x00, stream_id=2> 617 [ 0.027] send WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0> 618 (window_size_increment=33343) 619 [ 0.032] send WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=2> 620 (window_size_increment=33707) 621 [ 0.032] recv DATA frame <length=14645, flags=0x01, stream_id=2> 622 ; END_STREAM 623 [ 0.032] recv SETTINGS frame <length=0, flags=0x01, stream_id=0> 624 ; ACK 625 (niv=0) 626 [ 0.032] send GOAWAY frame <length=8, flags=0x00, stream_id=0> 627 (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[]) 628 629Using the ``-s`` option, ``nghttp`` prints out some timing information for 630requests, sorted by completion time: 631 632.. code-block:: text 633 634 $ nghttp -nas https://nghttp2.org/ 635 ***** Statistics ***** 636 637 Request timing: 638 responseEnd: the time when last byte of response was received 639 relative to connectEnd 640 requestStart: the time just before first byte of request was sent 641 relative to connectEnd. If '*' is shown, this was 642 pushed by server. 643 process: responseEnd - requestStart 644 code: HTTP status code 645 size: number of bytes received as response body without 646 inflation. 647 URI: request URI 648 649 see http://www.w3.org/TR/resource-timing/#processing-model 650 651 sorted by 'complete' 652 653 id responseEnd requestStart process code size request path 654 13 +37.19ms +280us 36.91ms 200 2K / 655 2 +72.65ms * +36.38ms 36.26ms 200 8K /stylesheets/screen.css 656 17 +77.43ms +38.67ms 38.75ms 200 3K /javascripts/octopress.js 657 15 +78.12ms +38.66ms 39.46ms 200 3K /javascripts/modernizr-2.0.js 658 659Using the ``-r`` option, ``nghttp`` writes more detailed timing data to 660the given file in HAR format. 661 662nghttpd - server 663++++++++++++++++ 664 665``nghttpd`` is a multi-threaded static web server. 666 667By default, it uses SSL/TLS connection. Use ``--no-tls`` option to 668disable it. 669 670``nghttpd`` only accepts HTTP/2 connections via NPN/ALPN or direct 671HTTP/2 connections. No HTTP Upgrade is supported. 672 673The ``-p`` option allows users to configure server push. 674 675Just like ``nghttp``, it has a verbose output mode for framing 676information. Here is sample output from ``nghttpd``: 677 678.. code-block:: text 679 680 $ nghttpd --no-tls -v 8080 681 IPv4: listen 0.0.0.0:8080 682 IPv6: listen :::8080 683 [id=1] [ 1.521] send SETTINGS frame <length=6, flags=0x00, stream_id=0> 684 (niv=1) 685 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 686 [id=1] [ 1.521] recv SETTINGS frame <length=12, flags=0x00, stream_id=0> 687 (niv=2) 688 [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] 689 [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] 690 [id=1] [ 1.521] recv SETTINGS frame <length=0, flags=0x01, stream_id=0> 691 ; ACK 692 (niv=0) 693 [id=1] [ 1.521] recv PRIORITY frame <length=5, flags=0x00, stream_id=3> 694 (dep_stream_id=0, weight=201, exclusive=0) 695 [id=1] [ 1.521] recv PRIORITY frame <length=5, flags=0x00, stream_id=5> 696 (dep_stream_id=0, weight=101, exclusive=0) 697 [id=1] [ 1.521] recv PRIORITY frame <length=5, flags=0x00, stream_id=7> 698 (dep_stream_id=0, weight=1, exclusive=0) 699 [id=1] [ 1.521] recv PRIORITY frame <length=5, flags=0x00, stream_id=9> 700 (dep_stream_id=7, weight=1, exclusive=0) 701 [id=1] [ 1.521] recv PRIORITY frame <length=5, flags=0x00, stream_id=11> 702 (dep_stream_id=3, weight=1, exclusive=0) 703 [id=1] [ 1.521] recv (stream_id=13) :method: GET 704 [id=1] [ 1.521] recv (stream_id=13) :path: / 705 [id=1] [ 1.521] recv (stream_id=13) :scheme: http 706 [id=1] [ 1.521] recv (stream_id=13) :authority: localhost:8080 707 [id=1] [ 1.521] recv (stream_id=13) accept: */* 708 [id=1] [ 1.521] recv (stream_id=13) accept-encoding: gzip, deflate 709 [id=1] [ 1.521] recv (stream_id=13) user-agent: nghttp2/1.0.0-DEV 710 [id=1] [ 1.521] recv HEADERS frame <length=41, flags=0x25, stream_id=13> 711 ; END_STREAM | END_HEADERS | PRIORITY 712 (padlen=0, dep_stream_id=11, weight=16, exclusive=0) 713 ; Open new stream 714 [id=1] [ 1.521] send SETTINGS frame <length=0, flags=0x01, stream_id=0> 715 ; ACK 716 (niv=0) 717 [id=1] [ 1.521] send HEADERS frame <length=86, flags=0x04, stream_id=13> 718 ; END_HEADERS 719 (padlen=0) 720 ; First response header 721 :status: 200 722 server: nghttpd nghttp2/1.0.0-DEV 723 content-length: 10 724 cache-control: max-age=3600 725 date: Fri, 15 May 2015 14:49:04 GMT 726 last-modified: Tue, 30 Sep 2014 12:40:52 GMT 727 [id=1] [ 1.522] send DATA frame <length=10, flags=0x01, stream_id=13> 728 ; END_STREAM 729 [id=1] [ 1.522] stream_id=13 closed 730 [id=1] [ 1.522] recv GOAWAY frame <length=8, flags=0x00, stream_id=0> 731 (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[]) 732 [id=1] [ 1.522] closed 733 734nghttpx - proxy 735+++++++++++++++ 736 737``nghttpx`` is a multi-threaded reverse proxy for HTTP/2, and 738HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server 739push. 740 741We reworked ``nghttpx`` command-line interface, and as a result, there 742are several incompatibles from 1.8.0 or earlier. This is necessary to 743extend its capability, and secure the further feature enhancements in 744the future release. Please read `Migration from nghttpx v1.8.0 or 745earlier 746<https://nghttp2.org/documentation/nghttpx-howto.html#migration-from-nghttpx-v1-8-0-or-earlier>`_ 747to know how to migrate from earlier releases. 748 749``nghttpx`` implements `important performance-oriented features 750<https://istlsfastyet.com/#server-performance>`_ in TLS, such as 751session IDs, session tickets (with automatic key rotation), OCSP 752stapling, dynamic record sizing, ALPN/NPN, forward secrecy and HTTP/2. 753``nghttpx`` also offers the functionality to share session cache and 754ticket keys among multiple ``nghttpx`` instances via memcached. 755 756``nghttpx`` has 2 operation modes: 757 758================== ================ ================ ============= 759Mode option Frontend Backend Note 760================== ================ ================ ============= 761default mode HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy 762``--http2-proxy`` HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy 763================== ================ ================ ============= 764 765The interesting mode at the moment is the default mode. It works like 766a reverse proxy and listens for HTTP/2, and HTTP/1.1 and can be 767deployed as a SSL/TLS terminator for existing web server. 768 769In all modes, the frontend connections are encrypted by SSL/TLS by 770default. To disable encryption, use the ``no-tls`` keyword in 771``--frontend`` option. If encryption is disabled, incoming HTTP/1.1 772connections can be upgraded to HTTP/2 through HTTP Upgrade. On the 773other hard, backend connections are not encrypted by default. To 774encrypt backend connections, use ``tls`` keyword in ``--backend`` 775option. 776 777``nghttpx`` supports a configuration file. See the ``--conf`` option and 778sample configuration file ``nghttpx.conf.sample``. 779 780In the default mode, ``nghttpx`` works as reverse proxy to the backend 781server: 782 783.. code-block:: text 784 785 Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server 786 [reverse proxy] 787 788With the ``--http2-proxy`` option, it works as forward proxy, and it 789is so called secure HTTP/2 proxy: 790 791.. code-block:: text 792 793 Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy 794 [secure proxy] (e.g., Squid, ATS) 795 796The ``Client`` in the above example needs to be configured to use 797``nghttpx`` as secure proxy. 798 799At the time of this writing, both Chrome and Firefox support secure 800HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to 801create a proxy.pac script like this: 802 803.. code-block:: javascript 804 805 function FindProxyForURL(url, host) { 806 return "HTTPS SERVERADDR:PORT"; 807 } 808 809``SERVERADDR`` and ``PORT`` is the hostname/address and port of the 810machine nghttpx is running on. Please note that Chrome requires a valid 811certificate for secure proxy. 812 813Then run Chrome with the following arguments: 814 815.. code-block:: text 816 817 $ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn 818 819The backend HTTP/2 connections can be tunneled through an HTTP proxy. 820The proxy is specified using ``--backend-http-proxy-uri``. The 821following figure illustrates how nghttpx talks to the outside HTTP/2 822proxy through an HTTP proxy: 823 824.. code-block:: text 825 826 Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) -- 827 828 --===================---> HTTP/2 Proxy 829 (HTTP proxy tunnel) (e.g., nghttpx -s) 830 831Benchmarking tool 832----------------- 833 834The ``h2load`` program is a benchmarking tool for HTTP/2. The UI of 835``h2load`` is heavily inspired by ``weighttp`` 836(https://github.com/lighttpd/weighttp). The typical usage is as 837follows: 838 839.. code-block:: text 840 841 $ h2load -n100000 -c100 -m100 https://localhost:8443/ 842 starting benchmark... 843 spawning thread #0: 100 concurrent clients, 100000 total requests 844 Protocol: TLSv1.2 845 Cipher: ECDHE-RSA-AES128-GCM-SHA256 846 Server Temp Key: ECDH P-256 256 bits 847 progress: 10% done 848 progress: 20% done 849 progress: 30% done 850 progress: 40% done 851 progress: 50% done 852 progress: 60% done 853 progress: 70% done 854 progress: 80% done 855 progress: 90% done 856 progress: 100% done 857 858 finished in 771.26ms, 129658 req/s, 4.71MB/s 859 requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored 860 status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx 861 traffic: 3812300 bytes total, 1009900 bytes headers, 1000000 bytes data 862 min max mean sd +/- sd 863 time for request: 25.12ms 124.55ms 51.07ms 15.36ms 84.87% 864 time for connect: 208.94ms 254.67ms 241.38ms 7.95ms 63.00% 865 time to 1st byte: 209.11ms 254.80ms 241.51ms 7.94ms 63.00% 866 867The above example issued total 100,000 requests, using 100 concurrent 868clients (in other words, 100 HTTP/2 sessions), and a maximum of 100 streams 869per client. With the ``-t`` option, ``h2load`` will use multiple native 870threads to avoid saturating a single core on client side. 871 872.. warning:: 873 874 **Don't use this tool against publicly available servers.** That is 875 considered a DOS attack. Please only use it against your private 876 servers. 877 878HPACK tools 879----------- 880 881The ``src`` directory contains the HPACK tools. The ``deflatehd`` program is a 882command-line header compression tool. The ``inflatehd`` program is a 883command-line header decompression tool. Both tools read input from 884stdin and write output to stdout. Errors are written to stderr. 885They take JSON as input and output. We (mostly) use the same JSON data 886format described at https://github.com/http2jp/hpack-test-case. 887 888deflatehd - header compressor 889+++++++++++++++++++++++++++++ 890 891The ``deflatehd`` program reads JSON data or HTTP/1-style header fields from 892stdin and outputs compressed header block in JSON. 893 894For the JSON input, the root JSON object must include a ``cases`` key. 895Its value has to include the sequence of input header set. They share 896the same compression context and are processed in the order they 897appear. Each item in the sequence is a JSON object and it must 898include a ``headers`` key. Its value is an array of JSON objects, 899which includes exactly one name/value pair. 900 901Example: 902 903.. code-block:: json 904 905 { 906 "cases": 907 [ 908 { 909 "headers": [ 910 { ":method": "GET" }, 911 { ":path": "/" } 912 ] 913 }, 914 { 915 "headers": [ 916 { ":method": "POST" }, 917 { ":path": "/" } 918 ] 919 } 920 ] 921 } 922 923 924With the ``-t`` option, the program can accept more familiar HTTP/1 style 925header field blocks. Each header set is delimited by an empty line: 926 927Example: 928 929.. code-block:: text 930 931 :method: GET 932 :scheme: https 933 :path: / 934 935 :method: POST 936 user-agent: nghttp2 937 938The output is in JSON object. It should include a ``cases`` key and its 939value is an array of JSON objects, which has at least the following keys: 940 941seq 942 The index of header set in the input. 943 944input_length 945 The sum of the length of the name/value pairs in the input. 946 947output_length 948 The length of the compressed header block. 949 950percentage_of_original_size 951 ``output_length`` / ``input_length`` * 100 952 953wire 954 The compressed header block as a hex string. 955 956headers 957 The input header set. 958 959header_table_size 960 The header table size adjusted before deflating the header set. 961 962Examples: 963 964.. code-block:: json 965 966 { 967 "cases": 968 [ 969 { 970 "seq": 0, 971 "input_length": 66, 972 "output_length": 20, 973 "percentage_of_original_size": 30.303030303030305, 974 "wire": "01881f3468e5891afcbf83868a3d856659c62e3f", 975 "headers": [ 976 { 977 ":authority": "example.org" 978 }, 979 { 980 ":method": "GET" 981 }, 982 { 983 ":path": "/" 984 }, 985 { 986 ":scheme": "https" 987 }, 988 { 989 "user-agent": "nghttp2" 990 } 991 ], 992 "header_table_size": 4096 993 } 994 , 995 { 996 "seq": 1, 997 "input_length": 74, 998 "output_length": 10, 999 "percentage_of_original_size": 13.513513513513514, 1000 "wire": "88448504252dd5918485", 1001 "headers": [ 1002 { 1003 ":authority": "example.org" 1004 }, 1005 { 1006 ":method": "POST" 1007 }, 1008 { 1009 ":path": "/account" 1010 }, 1011 { 1012 ":scheme": "https" 1013 }, 1014 { 1015 "user-agent": "nghttp2" 1016 } 1017 ], 1018 "header_table_size": 4096 1019 } 1020 ] 1021 } 1022 1023 1024The output can be used as the input for ``inflatehd`` and 1025``deflatehd``. 1026 1027With the ``-d`` option, the extra ``header_table`` key is added and its 1028associated value includes the state of dynamic header table after the 1029corresponding header set was processed. The value includes at least 1030the following keys: 1031 1032entries 1033 The entry in the header table. If ``referenced`` is ``true``, it 1034 is in the reference set. The ``size`` includes the overhead (32 1035 bytes). The ``index`` corresponds to the index of header table. 1036 The ``name`` is the header field name and the ``value`` is the 1037 header field value. 1038 1039size 1040 The sum of the spaces entries occupied, this includes the 1041 entry overhead. 1042 1043max_size 1044 The maximum header table size. 1045 1046deflate_size 1047 The sum of the spaces entries occupied within 1048 ``max_deflate_size``. 1049 1050max_deflate_size 1051 The maximum header table size the encoder uses. This can be smaller 1052 than ``max_size``. In this case, the encoder only uses up to first 1053 ``max_deflate_size`` buffer. Since the header table size is still 1054 ``max_size``, the encoder has to keep track of entries outside the 1055 ``max_deflate_size`` but inside the ``max_size`` and make sure 1056 that they are no longer referenced. 1057 1058Example: 1059 1060.. code-block:: json 1061 1062 { 1063 "cases": 1064 [ 1065 { 1066 "seq": 0, 1067 "input_length": 66, 1068 "output_length": 20, 1069 "percentage_of_original_size": 30.303030303030305, 1070 "wire": "01881f3468e5891afcbf83868a3d856659c62e3f", 1071 "headers": [ 1072 { 1073 ":authority": "example.org" 1074 }, 1075 { 1076 ":method": "GET" 1077 }, 1078 { 1079 ":path": "/" 1080 }, 1081 { 1082 ":scheme": "https" 1083 }, 1084 { 1085 "user-agent": "nghttp2" 1086 } 1087 ], 1088 "header_table_size": 4096, 1089 "header_table": { 1090 "entries": [ 1091 { 1092 "index": 1, 1093 "name": "user-agent", 1094 "value": "nghttp2", 1095 "referenced": true, 1096 "size": 49 1097 }, 1098 { 1099 "index": 2, 1100 "name": ":scheme", 1101 "value": "https", 1102 "referenced": true, 1103 "size": 44 1104 }, 1105 { 1106 "index": 3, 1107 "name": ":path", 1108 "value": "/", 1109 "referenced": true, 1110 "size": 38 1111 }, 1112 { 1113 "index": 4, 1114 "name": ":method", 1115 "value": "GET", 1116 "referenced": true, 1117 "size": 42 1118 }, 1119 { 1120 "index": 5, 1121 "name": ":authority", 1122 "value": "example.org", 1123 "referenced": true, 1124 "size": 53 1125 } 1126 ], 1127 "size": 226, 1128 "max_size": 4096, 1129 "deflate_size": 226, 1130 "max_deflate_size": 4096 1131 } 1132 } 1133 , 1134 { 1135 "seq": 1, 1136 "input_length": 74, 1137 "output_length": 10, 1138 "percentage_of_original_size": 13.513513513513514, 1139 "wire": "88448504252dd5918485", 1140 "headers": [ 1141 { 1142 ":authority": "example.org" 1143 }, 1144 { 1145 ":method": "POST" 1146 }, 1147 { 1148 ":path": "/account" 1149 }, 1150 { 1151 ":scheme": "https" 1152 }, 1153 { 1154 "user-agent": "nghttp2" 1155 } 1156 ], 1157 "header_table_size": 4096, 1158 "header_table": { 1159 "entries": [ 1160 { 1161 "index": 1, 1162 "name": ":method", 1163 "value": "POST", 1164 "referenced": true, 1165 "size": 43 1166 }, 1167 { 1168 "index": 2, 1169 "name": "user-agent", 1170 "value": "nghttp2", 1171 "referenced": true, 1172 "size": 49 1173 }, 1174 { 1175 "index": 3, 1176 "name": ":scheme", 1177 "value": "https", 1178 "referenced": true, 1179 "size": 44 1180 }, 1181 { 1182 "index": 4, 1183 "name": ":path", 1184 "value": "/", 1185 "referenced": false, 1186 "size": 38 1187 }, 1188 { 1189 "index": 5, 1190 "name": ":method", 1191 "value": "GET", 1192 "referenced": false, 1193 "size": 42 1194 }, 1195 { 1196 "index": 6, 1197 "name": ":authority", 1198 "value": "example.org", 1199 "referenced": true, 1200 "size": 53 1201 } 1202 ], 1203 "size": 269, 1204 "max_size": 4096, 1205 "deflate_size": 269, 1206 "max_deflate_size": 4096 1207 } 1208 } 1209 ] 1210 } 1211 1212inflatehd - header decompressor 1213+++++++++++++++++++++++++++++++ 1214 1215The ``inflatehd`` program reads JSON data from stdin and outputs decompressed 1216name/value pairs in JSON. 1217 1218The root JSON object must include the ``cases`` key. Its value has to 1219include the sequence of compressed header blocks. They share the same 1220compression context and are processed in the order they appear. Each 1221item in the sequence is a JSON object and it must have at least a 1222``wire`` key. Its value is a compressed header block as a hex string. 1223 1224Example: 1225 1226.. code-block:: json 1227 1228 { 1229 "cases": 1230 [ 1231 { "wire": "8285" }, 1232 { "wire": "8583" } 1233 ] 1234 } 1235 1236The output is a JSON object. It should include a ``cases`` key and its 1237value is an array of JSON objects, which has at least following keys: 1238 1239seq 1240 The index of the header set in the input. 1241 1242headers 1243 A JSON array that includes decompressed name/value pairs. 1244 1245wire 1246 The compressed header block as a hex string. 1247 1248header_table_size 1249 The header table size adjusted before inflating compressed header 1250 block. 1251 1252Example: 1253 1254.. code-block:: json 1255 1256 { 1257 "cases": 1258 [ 1259 { 1260 "seq": 0, 1261 "wire": "01881f3468e5891afcbf83868a3d856659c62e3f", 1262 "headers": [ 1263 { 1264 ":authority": "example.org" 1265 }, 1266 { 1267 ":method": "GET" 1268 }, 1269 { 1270 ":path": "/" 1271 }, 1272 { 1273 ":scheme": "https" 1274 }, 1275 { 1276 "user-agent": "nghttp2" 1277 } 1278 ], 1279 "header_table_size": 4096 1280 } 1281 , 1282 { 1283 "seq": 1, 1284 "wire": "88448504252dd5918485", 1285 "headers": [ 1286 { 1287 ":method": "POST" 1288 }, 1289 { 1290 ":path": "/account" 1291 }, 1292 { 1293 "user-agent": "nghttp2" 1294 }, 1295 { 1296 ":scheme": "https" 1297 }, 1298 { 1299 ":authority": "example.org" 1300 } 1301 ], 1302 "header_table_size": 4096 1303 } 1304 ] 1305 } 1306 1307The output can be used as the input for ``deflatehd`` and 1308``inflatehd``. 1309 1310With the ``-d`` option, the extra ``header_table`` key is added and its 1311associated value includes the state of the dynamic header table after the 1312corresponding header set was processed. The format is the same as 1313``deflatehd``. 1314 1315libnghttp2_asio: High level HTTP/2 C++ library 1316---------------------------------------------- 1317 1318libnghttp2_asio is C++ library built on top of libnghttp2 and provides 1319high level abstraction API to build HTTP/2 applications. It depends 1320on the Boost::ASIO library and OpenSSL. Currently libnghttp2_asio 1321provides both client and server APIs. 1322 1323libnghttp2_asio is not built by default. Use the ``--enable-asio-lib`` 1324configure flag to build libnghttp2_asio. The required Boost libraries 1325are: 1326 1327* Boost::Asio 1328* Boost::System 1329* Boost::Thread 1330 1331The server API is designed to build an HTTP/2 server very easily to utilize 1332C++14 anonymous functions and closures. The bare minimum example of 1333an HTTP/2 server looks like this: 1334 1335.. code-block:: cpp 1336 1337 #include <iostream> 1338 1339 #include <nghttp2/asio_http2_server.h> 1340 1341 using namespace nghttp2::asio_http2; 1342 using namespace nghttp2::asio_http2::server; 1343 1344 int main(int argc, char *argv[]) { 1345 boost::system::error_code ec; 1346 http2 server; 1347 1348 server.handle("/", [](const request &req, const response &res) { 1349 res.write_head(200); 1350 res.end("hello, world\n"); 1351 }); 1352 1353 if (server.listen_and_serve(ec, "localhost", "3000")) { 1354 std::cerr << "error: " << ec.message() << std::endl; 1355 } 1356 } 1357 1358Here is sample code to use the client API: 1359 1360.. code-block:: cpp 1361 1362 #include <iostream> 1363 1364 #include <nghttp2/asio_http2_client.h> 1365 1366 using boost::asio::ip::tcp; 1367 1368 using namespace nghttp2::asio_http2; 1369 using namespace nghttp2::asio_http2::client; 1370 1371 int main(int argc, char *argv[]) { 1372 boost::system::error_code ec; 1373 boost::asio::io_service io_service; 1374 1375 // connect to localhost:3000 1376 session sess(io_service, "localhost", "3000"); 1377 1378 sess.on_connect([&sess](tcp::resolver::iterator endpoint_it) { 1379 boost::system::error_code ec; 1380 1381 auto req = sess.submit(ec, "GET", "http://localhost:3000/"); 1382 1383 req->on_response([](const response &res) { 1384 // print status code and response header fields. 1385 std::cerr << "HTTP/2 " << res.status_code() << std::endl; 1386 for (auto &kv : res.header()) { 1387 std::cerr << kv.first << ": " << kv.second.value << "\n"; 1388 } 1389 std::cerr << std::endl; 1390 1391 res.on_data([](const uint8_t *data, std::size_t len) { 1392 std::cerr.write(reinterpret_cast<const char *>(data), len); 1393 std::cerr << std::endl; 1394 }); 1395 }); 1396 1397 req->on_close([&sess](uint32_t error_code) { 1398 // shutdown session after first request was done. 1399 sess.shutdown(); 1400 }); 1401 }); 1402 1403 sess.on_error([](const boost::system::error_code &ec) { 1404 std::cerr << "error: " << ec.message() << std::endl; 1405 }); 1406 1407 io_service.run(); 1408 } 1409 1410For more details, see the documentation of libnghttp2_asio. 1411 1412Python bindings 1413--------------- 1414 1415The ``python`` directory contains nghttp2 Python bindings. The 1416bindings currently provide HPACK compressor and decompressor classes 1417and an HTTP/2 server. 1418 1419The extension module is called ``nghttp2``. 1420 1421``make`` will build the bindings and target Python version is 1422determined by the ``configure`` script. If the detected Python version is not 1423what you expect, specify a path to Python executable in a ``PYTHON`` 1424variable as an argument to configure script (e.g., ``./configure 1425PYTHON=/usr/bin/python3.8``). 1426 1427The following example code illustrates basic usage of the HPACK compressor 1428and decompressor in Python: 1429 1430.. code-block:: python 1431 1432 import binascii 1433 import nghttp2 1434 1435 deflater = nghttp2.HDDeflater() 1436 inflater = nghttp2.HDInflater() 1437 1438 data = deflater.deflate([(b'foo', b'bar'), 1439 (b'baz', b'buz')]) 1440 print(binascii.b2a_hex(data)) 1441 1442 hdrs = inflater.inflate(data) 1443 print(hdrs) 1444 1445The ``nghttp2.HTTP2Server`` class builds on top of the asyncio event 1446loop. On construction, *RequestHandlerClass* must be given, which 1447must be a subclass of ``nghttp2.BaseRequestHandler`` class. 1448 1449The ``BaseRequestHandler`` class is used to handle the HTTP/2 stream. 1450By default, it does nothing. It must be subclassed to handle each 1451event callback method. 1452 1453The first callback method invoked is ``on_headers()``. It is called 1454when HEADERS frame, which includes the request header fields, has arrived. 1455 1456If the request has a request body, ``on_data(data)`` is invoked for each 1457chunk of received data. 1458 1459Once the entire request is received, ``on_request_done()`` is invoked. 1460 1461When the stream is closed, ``on_close(error_code)`` is called. 1462 1463The application can send a response using ``send_response()`` method. 1464It can be used in ``on_headers()``, ``on_data()`` or 1465``on_request_done()``. 1466 1467The application can push resources using the ``push()`` method. It must be 1468used before the ``send_response()`` call. 1469 1470The following instance variables are available: 1471 1472client_address 1473 Contains a tuple of the form (host, port) referring to the 1474 client's address. 1475 1476stream_id 1477 Stream ID of this stream. 1478 1479scheme 1480 Scheme of the request URI. This is a value of :scheme header 1481 field. 1482 1483method 1484 Method of this stream. This is a value of :method header field. 1485 1486host 1487 This is a value of :authority or host header field. 1488 1489path 1490 This is a value of :path header field. 1491 1492The following example illustrates the HTTP2Server and 1493BaseRequestHandler usage: 1494 1495.. code-block:: python 1496 1497 #!/usr/bin/env python3 1498 1499 import io, ssl 1500 import nghttp2 1501 1502 class Handler(nghttp2.BaseRequestHandler): 1503 1504 def on_headers(self): 1505 self.push(path='/css/bootstrap.css', 1506 request_headers = [('content-length', '3')], 1507 status=200, 1508 body='foo') 1509 1510 self.push(path='/js/bootstrap.js', 1511 method='GET', 1512 request_headers = [('content-length', '10')], 1513 status=200, 1514 body='foobarbuzz') 1515 1516 self.send_response(status=200, 1517 headers = [('content-type', 'text/plain')], 1518 body=io.BytesIO(b'nghttp2-python FTW')) 1519 1520 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 1521 ctx.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 1522 ctx.load_cert_chain('server.crt', 'server.key') 1523 1524 # give None to ssl to make the server non-SSL/TLS 1525 server = nghttp2.HTTP2Server(('127.0.0.1', 8443), Handler, ssl=ctx) 1526 server.serve_forever() 1527 1528Contribution 1529------------ 1530 1531[This text was composed based on 1.2. License section of curl/libcurl 1532project.] 1533 1534When contributing with code, you agree to put your changes and new 1535code under the same license nghttp2 is already using unless stated and 1536agreed otherwise. 1537 1538When changing existing source code, do not alter the copyright of 1539the original file(s). The copyright will still be owned by the 1540original creator(s) or those who have been assigned copyright by the 1541original author(s). 1542 1543By submitting a patch to the nghttp2 project, you (or your employer, as 1544the case may be) agree to assign the copyright of your submission to us. 1545.. the above really needs to be reworded to pass legal muster. 1546We will credit you for your 1547changes as far as possible, to give credit but also to keep a trace 1548back to who made what changes. Please always provide us with your 1549full real name when contributing! 1550 1551See `Contribution Guidelines 1552<https://nghttp2.org/documentation/contribute.html>`_ for more 1553details. 1554 1555Reporting vulnerability 1556----------------------- 1557 1558If you find a vulnerability in our software, please send the email to 1559"tatsuhiro.t at gmail dot com" about its details instead of submitting 1560issues on github issue page. It is a standard practice not to 1561disclose vulnerability information publicly until a fixed version is 1562released, or mitigation is worked out. 1563 1564In the future, we may setup a dedicated mail address for this purpose. 1565 1566Release schedule 1567---------------- 1568 1569In general, we follow `Semantic Versioning <http://semver.org/>`_. We 1570release MINOR version update every month, and usually we ship it 1571around 25th day of every month. 1572 1573We may release PATCH releases between the regular releases, mainly for 1574severe security bug fixes. 1575 1576We have no plan to break API compatibility changes involving soname 1577bump, so MAJOR version will stay 1 for the foreseeable future. 1578 1579License 1580------- 1581 1582The MIT License 1583