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 LibreSSL >= 3.8.1; or aws-lc >= 1.19.0; or
65 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 LibreSSL (does not support 0RTT); or aws-lc; or
129 `BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
130 6ab7c1482bf4cdc91c87bc512aaf68ffb18975ec)
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/tag/v1.3.0>`_. nghttpx
148requires eBPF program for reloading its configuration and hot swapping
149its executable.
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++ >= 1.12 and
154clang++ >= 1.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.26.0 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.3.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.5.0 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.3.0 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