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