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