nghttp2.org

HTTP/2 C library and tools

Host Lucid Erlang HTTP/2 Server

nghttp2.org now hosts Lucid HTTP/2 server written in Erlang. The access endpoint is https://nghttp2.org:3456/. Currently it returns simple html content including request headers. It only speaks h2-14.

Since Erlang SSL module does not support AEAD cipher suites, Firefox nightly refuses to connect to this server. To workaround this, open about:config in Firefox and set network.http.spdy.enforce-tls-profile to false.

Nghttp2 v0.6.1

We just released nghttp2 v0.6.1. This release fixes compile error in bundled application code on OSX. No library code has been changed since v0.6.0.

Nghttp2 v0.6.0

Finally, we released nghttp2 v0.6.0! It implements h2-14 and header compression HPACK 09.

In this release, we decided to hide the details of nghttp2_session_callbacks struct. The reason of this decision is to avoid so name bump each time we add new callback. Actually, we added 2 new callbacks in this release. We expect more to come, so it is a good time to make API open for extension.

We successfully performed interop testing with Firefox, Jetty and Twitter.

If you are shrpx users from spdylay project, this is a good time to migrate to nghttpx, which supports SPDY proxy as well.

Anyway, the every release for OSS project is happy time. Have fun!

Update to H2-14

Today We updated nghttp2 to support latest HTTP/2 draft, h2-14. The source code is available on github. This server is advertize h2-14 now.

Here is a quick summary of the changes since h2-13:

  • Frame length field was expanded to 24 bits.
  • The pseudo headers (aka, colon (:) headers) handling is tightened up. Now unexpected pseudo headers are subject to stream error.
  • WINDOW_UPDATE with 0 window-size is now treated as error.
  • END_SEGMENT flag was removed.
  • SETTINGS_MAX_FRAME_SIZE and SETTINGS_MAX_HEADER_LIST_SIZE were added.
  • 1xx status codes, except for 101, are now supported.
  • Removed 0x00 concatenation rule.
  • HPACK: reference set was removed.
  • HPACK: static header table is now in front of dynamic header table.
  • HPACK: No copy when static header table entry is referenced.

Nghttp2 v0.5.1 Released

We happily announce the immediate availability of nghttp2 v0.5.1. The supported HTTP/2 protocol remains to h2-13.

This release fixes HPACK integer decoding bug, which occurs when encoded integer byte sequence crosses frame boundary or packet.

Nghttp2 v0.5.0 Released

We happily announce the immediate availability of nghttp2 v0.5.0. The supported HTTP/2 protocol is now h2-13.

The changes since h2-12 were described in the previous post. We still supports ALTSVC frame in this release, but it may be removed in the future release since it is now in the separate document. The BLOCKED frame was completely removed from the source code.

Update to H2-13

nghttp2 was updated to HTTP/2 draft-13 and HPACK draft-08.

The major changes are:

  • Simplified padding (Pad High field was removed)
  • No padding for CONTINUATION frame.
  • ALTSVC and BLOCKED frame was moved to extension. The current nghttp2 source code contains ALTSVC and BLOCKED as extension based on draft-12. But their specification may change and they may be dropped from nghttp2 public API until their specifications are settled.
  • Per-frame compression was removed.
  • Huffman code table and static header table were updated.

The https endpoint for nghttp2.org now requires TLSv1.2 and DHE or EDCHE with GCM cipher suite for HTTP/2 connection. If HTTP/2 was negotiated and these requirements are not met, connection error will be issued with the error code INADEQUATE_SECURITY.

Nghttp2 v0.4.1 Released

nghttp2 v0.4.1 just released today. It is mainly a bug fix release. The supported HTTP/2 protocol version remains h2-12.

Although this release is tagged as bug fix release, nghttpx got some improvements. Firstly, --npn-list option now works with ALPN. Secondly, * is officially allowed as <HOST> parameter in --frontend option and it means wildcard address, which can bind to both IPv4 and IPv6 addresses.

Httpbin for HTTP/2 Clients

httpbin is a HTTP Request & Response Service developped by A Kenneth Reitz Project. Currently it only serves in HTTP/1.1.

nghttp2.org now serves its functionality in HTTP/2 and SPDY. You can access the service here.

Currently, some json elements (e.g., url) are a bit strange due to the fact that httpbin service is reverse proxied.

BLOCKED Frame Did Not Block DATA Frame?

nghttp HTTP/2 client included in nghttp2 has a nice feature to show the incoming and outgoing HTTP/2 frames. It is extremely usable for debugging.

Here is a snippet of the log nghttp produced today:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[  0.359] recv HEADERS frame <length=154, flags=0x04, stream_id=1>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.359] recv DATA frame <length=3798, flags=0x00, stream_id=1>
[  0.362] recv DATA frame <length=4096, flags=0x00, stream_id=1>
[  0.362] send HEADERS frame <length=27, flags=0x05, stream_id=3>
          ; END_STREAM | END_HEADERS
          (padlen=0)
          ; Open new stream
[  0.364] recv DATA frame <length=4096, flags=0x00, stream_id=1>
[  0.391] recv DATA frame <length=2715, flags=0x00, stream_id=1>
[  0.392] recv DATA frame <length=0, flags=0x01, stream_id=1>
[  0.394] recv HEADERS frame <length=40, flags=0x04, stream_id=3>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.394] recv DATA frame <length=3798, flags=0x00, stream_id=3>
[  0.394] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.402] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.406] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.430] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.430] send WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
          (window_size_increment=34887)
[  0.434] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.435] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.438] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.442] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.442] send WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=3>
          (window_size_increment=36566)
[  0.470] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.471] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.474] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.475] recv DATA frame <length=1976, flags=0x00, stream_id=3>
[  0.475] recv BLOCKED frame <length=0, flags=0x00, stream_id=0>
[  0.488] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.488] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.488] recv DATA frame <length=4096, flags=0x00, stream_id=3>
[  0.489] recv DATA frame <length=2417, flags=0x00, stream_id=3>
[  0.489] recv BLOCKED frame <length=0, flags=0x00, stream_id=3>

When you see this, you may wonder why BLOCKED frame recieved at t=0.475 was followed by DATA frame. BLOCKED with stream_id=0 means connection level window size is depleted, and server is unable to send more DATA until it receives WINDOW_UPDATE frame from client. There is no WINDOW_UPDATE between t=0.475 and t=0.488, so you may think this must be a mistake, server has a bug.

Of course not. WINDOW_UPDATE with stream_id=0 was already sent t=0.430. But due to latency, before it reached at the server, server used all available window size and sent BLOCKED frame. After that, the server finally received the WINDOW_UPDATE from client and update its window size and started to send DATA frame again.

BLOCKED and WINDOW_UPDATE frames