In this release, we fixed assertion failure in nghttpx on premature
connection termination during last phase of TLS handshake. In library
code, when request HEADERS frame cannot be sent due to the too large
header fields, we previously did not open stream, so on
nghttp2_on_frame_not_send_callback, we could not retrieve per-stream
user data using nghttp2_session_get_stream_user_data(). Now it
first opens stream and then checks the size of headers, so
nghttp2_session_get_stream_user_data() can work.
For nghttpx, we added x-http2-push header field for pushed resource.
This practice is also done in h2o web
server.
In this release, we fixed several bugs in library and added
improvements to h2load and nghttpx.
We fixed rough edges of stream priority handling in nghttp2 library
code. It was minor, but worth updating.
We shipped init script for nghttpx, but it missed --daemon option.
So unless it is enabled in its configuration file, start/stop script
hangs. This bug was fixed by Tomasz Buchert.
Lucas Pardue improved validation of timing script input in h2load.
Previously, in h2load, we measured TTFB (time to first byte) in first
socket read, rather than first byte of response body. Now it is
corrected.
We added
PROXY protocol version 1
support to nghttpx. If --accept-proxy-protocol option is used,
nghttpx expects PROXY protocol line on frontend connection. The
obtained client address is used in X-Forwarded-For header field.
We extended push functionality in nghttpx, and it can now push
resources specified in Link header fields which come from HTTP/2
backend. Also we now allow absolute URI in Link header fields.
We added mruby support in nghttpx.
It is disabled by default. Use --with-mruby configure option to
enable it. The nghttp2 archive includes mruby source code, so user
doesn’t have to download it themselves. Please note that mruby
package in Debian/Ubuntu does not work with nghttpx, since it does not
enable C++ ABI mode. nghttpx runs given mruby scripts in 2 phases:
request phase, and response phase. The request phase is when set of
request header fields are received from client. The response phase is
when set of response header fields are received from backend server.
We have
documented all mruby APIs.
User can override request/response header fields, change request path,
and even return custom response without forwarding request to backend
or discarding response from backend. Checkout
examples.
In this release, we added upper limit for the number of the streams
pushed from server and not yet opened for client side session.
Specifically, these streams are in “reserved (remote)” state as
described in
RFC 7540, Section 5.1..
The thing is RFC 7540 does not say anything about the upper limit of
these streams. It says the number of maximum concurrent streams, but
it only applies to the opened streams, not applied to streams in
“reserved (remote)” state. From this release, nghttp2 library limits
the number of these streams less than or equal to 200 by default.
Applications can change this limit by using
nghttp2_option_set_max_reserved_remote_streams() function. Those
streams which exceed this limit will be automatically closed with
RST_STREAM frame.
We added public APIs to expose dependency tree information. The
nghttp2 library handles HTTP/2 dependency priority just fine, but
there is a need to access to the dependency tree from applications.
One of the use case is to schedule stream handling in threads. In the
most of the cases, the number of available threads are smaller than
incoming streams. Applications can get the dependency information
from nghttp2 library, and schedule them in the order by the priority.
nghttp2_session_find_stream() function will return stream object
with the given stream ID. Applications can traverse dependency tree
from this object. nghttp2_session_get_root_stream() will return the
stream object which is the root of whole dependency tree. See
nghttp2_stream_* functions to access the properties of stream
object.
We rewrite priority tree handling. Now it is simpler and robust. We
now use priority queue per stream, which contains the stream which has
ready to send a frame, or one of its descendants have a frame to send.
We maintain invariant that if a stream is queued, then its ancestors
are also queued (except for root). When we re-schedule stream after
transmission, we re-schedule all ancestors, so that streams on the
other path can get a chance to send. The basic idea is the same with
h2o’s scheduler, but there are
differences in the details.
We found that openssl ocsp command exits withs status code 0 even if
ocsp query or validation was failed. We added extra code to
fetch-ocsp-response script to handle these situations.
Now nghttpx and nghttpd terminate HTTP/2 connection with GOAWAY of
error code INADEQUATE_SECURITY if one of black listed cipher suites
(see
RFC 7540, Appendix A)
was negotiated.
Tomasz Buchert improved handling of /dev/stdout and /dev/stderr for
logging in nghttpx.
We added HEAD method support to nghttpd.
Lucas Pardue added Timing-script and base URI support to h2load. See
#330 for more
details.
Nora Shoemaker added timeout options to h2load. See
#331 for more
details.
We released v1.2.0 in Aug 9, but immediately after the release, we
found some stability issues in nghttpx. We have done some hard work
to fix them, and here is the v1.2.1 release.
Since most of the interesting stuff was done in v1.2.0, we also
describe the changes in v1.2.0 in this blog post.
Previously, nghttp2 library only allow one outgoing in-flight SETTINGS
frame. Now its limitation was gone, and application can issue
multiple SETTINGS frame as it wants.
Previously, nghttp2 library allows incoming dynamic table size update
in the middle of compressed header block. But RFC 7541 clearly states
that it is restricted to the beginning of the header block. Now
nghttp2 checks this restriction strictly. nghttp2 library also
strictly checks whether peer sends dynamic table size update in
response to header table change in SETTINGS.
Tom Harwood offered the patch to improve English text in tutorial
documentation. Now they should be more readable.
nghttpx gets many advanced features in this release (and ironically
(or inevitably?), it was the cause of the instability issue). Now it
supports sharing session cache and TLS ticket keys among multiple
nghttpx instance using memcached. We use OpenSSL, and basically it
does not support asynchronous session cache lookup, but we use the
same trick invented by Kazuho Oku in his awesome
h2o project. If memcached based TLS
ticket key sharing is not used, nghttpx generates TLS ticket keys
internally as usual. From this release, it now generates new key
every 1 hour, and its life time is 12 hours.
We added --tls-ticket-key-cipher option to change the cipher to
encrypt session ticket. Currently, AES-128-CBC and AES-256-CBC are
supported. Previously, we did not have this option, and cipher is
always AES-128-CBC. Because of limitation in current OpenSSL
implementation, we cannot use AES-GCM for ticket encryption at the
moment.
Previously nghttpx HTTP/2 backend connection did not enable any TLS
resumption. Now it is enabled.
Previously, by default, nghttpx rewrote Host (or :authority) header
field for backend request using backend server’s address. This was
done because apache and nginx do this by default. But we have heard
that in most of the use case for nghttpx, users disable this feature
using --no-host-rewrite. So we decided to not to rewrite Host
header field by default. Instead, we added --host-rewrite option to
enable rewrite.
We fixed bug in nghttpd that it sent response body even if status code
was 304.
Nora Shoemaker sent us a patch to add connection rate based execution.
See #299 for the
intended use case.
We should have written this blog after v1.1.0 was released, but we
found some memory leaks in nghttpx, and while tracing this, we have
found another issue. Although these issues have existed well before
v1.1.0, we decided to fix these issues, and make an another release.
As a result, v1.1.0 became very short term release, but it contains
many changes, so we describe changes since v1.0.5 here.
First thing first, the bug fixes in libnghttp2 library. We found bug
which causes receive window exhaustion if automatic flow control
feature is disabled, and peer sends illegal HTTP message body.
Gabi Davar kindly offered a patch to enhance msvc build and python
setup script.
Klaus Ziegler sent us a patch to compile nghttp2 with IRIX gcc-4.7.
nghttp now gets --max-concurrent-streams option to control the
concurrency. Regarding nghttp, acesso sent us a patch to add comment
on HAR on pushed objects.
We fixed memory leaks and stability issues in nghttpx.
nghttpx now supports backend routing based on request host and path by
extending -b option. The detailed syntax is explained in
nghttpx man page.
The routing pattern is very similar to ServeMux in net/http package
from Go programming language. For example, if we want to route
request to “/httpbin/” to 127.0.0.1 port 8000, and rest of the
requests to 127.0.0.1 port 8081, we can write configuration file like
so:
The second rule above is equivalent to 127.0.0.1,8001;/, which
matches all request paths. This is called catch-all pattern, and
nghttpx requires this catch-all pattern.
All requests whose host header field (:authority header field for
HTTP/2) are routed to 127.0.0.1 port 8000, and all requests for
blog.example.org are routed to 127.0.0.1 port 8080.
This host-path based routing is available for both HTTP/1 and HTTP/2
backend (in other words, it is enabled in default mode,
--http2-bridge and --client). It is disabled if -s or -p is
given.
nghttpx also gets --include option to include configurations from
another file. This is useful to share configurations between
different nghttpx instances. The accesslog format variable now can be
enclosed with curly braces for disambiguation (e.g.,
${remote_addr}). SSL/TLS related log variables, such as TLS
protocol version, ciphers, etc, have been also added.
h2load gets --cipher option to specify specific cipher suites to
use.
This release fixes the bug in nghttpx that causes crash if
--http2-bridge is used, and both frontend and backend enable TLS,
and OCSP stapling is enabled. It also fixes the another bug in
priority handling.
This release fixes the bug that PRIORITY frame including dependency to
itself for idle stream resulted in fatal error from
nghttp2_session_mem_recv or nghttp2_session_recv in server-side
session. Now it is treated gracefully, and GOAWAY of type
PROTOCOL_ERROR is issued.
We optimized priority tree handling to Firefox style dependency tree,
and it dramatically speeds up the processing. The worst case,
linearly linked dependency tree, is also much improved.
Now LibreSSL can be used to build nghttp2 applications.
ocsp-fetch-response script also supports LibreSSL too.
We fixed the bug in nghttpx that x-forwarded-proto header field did
not reflect the frontend scheme if used with HTTP/2 backend.
This release fixes the bug which causes connection window exhaustion
if automatic flow-control is disabled
(nghttp2_option_set_no_auto_window_update()) and certain race
condition is met. When this happened, remote peer could not send any
more DATA because there was no connection window left.
For Windows build, we now define NGHTTP2_EXTERN to
__declspec(dllimport) when using nghttp2 library.
We translated fetch-ocsp-response script into Python, and it is now
under script directory.
We got several patches to enhance Python API from Fabian Wiesel.
We fixed the bug in libevent-client that included broken :path in
request if request URI did not contain path part.
For nghttpx, we added --add-request-header option to add arbitrary
header fields to backend server. We also enabled generic HTTP Upgrade
in HTTP/1.1 frontend (HTTP/2 disallows this, so it is not available).
This means nghttpx now can proxy WebSocket connection between client
and backend server.