Previously we just assumed that if same settings ID is found in
SETTINGS, it is enough to process last seen entry. But it turns out
it is not enough for SETTINGS_HEADER_TABLE_SIZE. If we have 0 and
4096 for SETTINGS_HEADER_TABLE_SIZE in one SETTINGS, we must first
shrink dynamic table to 0 and then enlarge it to 4096. This means
that we have to remember the minimum value and last value.
Add last_stream_id parameter to nghttp2_submit_goaway(). To terminate
connection immediately with application chosen last stream ID,
nghttp2_session_terminate_session2() was added.
ALTSVC and BLOCKED frames are now extension frames. To add new
extension frame without modifying nghttp2_frame union, which causes so
name bump, we separated extension frames from core frames.
nghttp2_frame includes generic nghttp2_extension. The payload member
of nghttp2_extension will point to the structure of extension frame
payload. The frame types of extension frames are defined in
nghttp2_ext_frame_type.
It is generally useful to know what is the cause of the error. Since
we expose HPACK API, it is friendly to tell application the
insufficient buffer size is a culprit.
Use this macro in Python sources. Python module constant
HD_DEFLATE_HD_TABLE_BUFSIZE_MAX was renamed as
DEFLATE_MAX_HEADER_TABLE_SIZE since the previous name was awkward.
Previously stream ID was assigned just before HEADERS or PUSH_PROMISE
was serialized and nghttp2_submit_{request, headers, push_promise} did
not return stream ID. The application has to check assigned stream ID
using before_frame_send_callback. Now it is apparent that priority is
meant to DATA transfer only. Also application can reorder the
requests if it wants. Therefore we can assign stream ID in
nghttp2_submit_* functions and return stream ID from them. With this
change, now application does not have to check stream ID using
before_frame_send_callback and its code will be simplified.
We inherited gzip compression API from spdylay codebase. In spdylay,
the cost of having such API is almost free because spdylay requires
zlib for header compression. nghttp2 no longer uses gzip to header
compression. zlib dependency exists just for gzip compression API,
which is not an essential. So we decided to move gzip code to under
src and remove zlib dependency from libnghttp2 itself. As nghttp2
package, we depend on zlib to compile tools under src.
Currently, nghttpd server only compresses files whose extensions are
one of .html, .js, .css and .txt. nghttp advertises its support of
per-frame compression in SETTINGS frame. To implement this feature,
we added 2 public API: nghttp2_session_get_remote_settings() and
nghttp2_gzip_inflate_finished().
Callback function invoked to adjust priority value for request
HEADERS.
Since the application doesn’t know stream ID when it submits
requests, it may not be able to add correct priority value to HEADERS
frame and forced to use follwing PRIORITY frame. The purpose of this
callback is give the chance to the application to adjust priority
value with the latest information it has just before transmission so
that correct priority is included in HEADERS frame and it doesn’t
have to send additional PRIORITY frame.
The library interface supports compressed DATA. The library does not
deflate nor inflate data payload. When sending data, an application
has to compress data and set NGHTTP2_DATA_FLAG_COMPRESSED to
data_flags parameter in nghttp2_data_source_read_callback. On
receiving, flags parameter in nghttp2_on_data_chunk_recv_callback
includes NGHTTP2_FLAG_COMPRESSED. An application should check the
flags and inflate data as necessary. Since compression context is per
frame, when DATA is seen in nghttp2_on_frame_recv_callback, an
application should reset compression context.
To make adding new option easier, we decided to make the details of
option struct private and hide it from public API. We provide
functions to set individual option value.
NGHTTP2_CLIENT_CONNECTION_PREFACE has the same content with
NGHTTP2_CLIENT_CONNECTION_HEADER, which is now obsoleted by
NGHTTP2_CLIENT_CONNECTION_PREFACE.
This function behaves like nghttp2_session_send(), but it does not
use nghttp2_send_callback to send data. Instead, it returns the
serialized data to trasmit and its length to the caller.
Now previous padding options are removed and instead we added
select_padding_callback to select padding length for each frame
by application. If this callback is not implemented by application,
no padding is added.
This change also fixes the broken session_detect_idle_stream()
if stream_id is our side.
Previously, there is inconsistency when on_frame_recv_callback
is called between HEADERS/PUSH_PROMISE and the other frames.
For former case, it is called before header block, in latter
case, it is called after whole frame is received. To make it
consistent, we call on_frame_recv_callback for HEADERS/PUSH_PROMISE
after its frame is fully received. Since on_frame_recv_callback
can signal the end of header block, we replaced on_end_headers_callback
with on_begin_headers_callback, which is called when the reception
of the header block is started.
nghttp2_data is added to nghttp2_frame union. When DATA is
received, nghttp2_on_frame_recv_callback is called. When DATA is
sent, nghttp2_on_frame_send_callback is called.
Remove the check to see that stream exists at the time when submitting
DATA, PRIORITY and WINDOW_UPDATE. We will do this check when we actually
serialize and send them off to the network (or application provided
buffer).
nghttp2 library itself now accept octet header/value pairs,
completely not restricted by HTTP/1 header name/value rule.
The applications may impose restriction about them using
validators.
Now, in nghttp2_on_frame_recv_callback, nva and nvlen in
HEADERS and PUSH_PROMISE frames are always NULL and 0 respectively.
The header name/value pairs are emitted successive
nghttp2_on_header_callback functions. The end of header fields are
signaled with nghttp2_on_end_headers_callback function.
Since NGHTTP2_ERR_PAUSE for nghttp2_on_frame_recv_callback is
introduced to handle header block, it is now deprecated.
Instead, nghttp2_on_header_callback can be paused using
NGHTTP2_ERR_PAUSE.
nghttp2_session_client_new2 and nghttp2_session_server_new2 take
additional parameters which specifies session options.
nghttp2_set_option is somewhat crumsy because of type checking.
Now we use nghttp2_opt_set, which specifies individual options with
types. We changed the value of nghttp2_opt, so this change will
require re-compile.
It is not clear that SETTINGS_ENABLE_PUSH = 0 disallows HEADERS
to the reserved streams. For now, we just check the reception
and transmission of PUSH_PROMISE against SETTINGS_ENABLE_PUSH.
The NGHTTP2_ERR_PAUSE library error code is introduced to pause
the execution of nghttp2_session_mem_recv() when that error code
is returned from nghttp2_on_frame_recv_callback or
nghttp2_on_data_chunk_recv_callback. If this happens, the parameters
available for both callbacks are retained until the application
calls nghttp2_session_continue(). The application must retain
input bytes which was used to produce the frame.
After successful call of nghttp2_session_continue, the application
can continue to call nghttp2_session_mem_recv() to process
additional data.
This function is similar to nghttp2_submit_request and the
difference is it takes an array of nghttp2_nv as name/value pairs.
It is useful if name/value pairs is not NULL-terminated in the
application code.
Now NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is split into 2 options:
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE and
NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE.
This is preparation for the upcoming removal of END_FLOW_CONTROL
flag. For nghttpx, instead of using END_FLOW_CONTROL to disable
connection-level flow control, increase window size by large
enough value, which is friendly way to current chromium
implementation.
If resultant length of a frame exceeds the maximum value (which is
2**24 - 1 for SPDY/2 and 3), SPDYLAY_ERR_FRAME_TOO_LARGE is used to
indicate this error. This error will be notified by
on_ctrl_not_send_callback.
spdylay_npn_get_proto_list() returns a pointer to the supported SPDY
version list. The element of the list is spdylay_npn_proto struct. It
contains all SPDY version information this library supports. The
application can use this information to configure NPN protocol
offerings/selection.
This option sets maximum receive buffer size for incoming control
frame. Basically the library checks the length field of the incoming
control frame. For frames with name/value header block, the library
also checks the length of inflated block is also under the limit. This
is done while incrementally inflating block. If the length of frames
with name/value header block exceeds the limit, the library will issue
RST_STREAM with FRAME_TOO_LARGE. For other frames, it will issue
GOAWAY.
Current SPDY/3 spec does not clearly prohibit to send
delta_window_size which makes resulting window size more than initial
window size. For this reason, spdylay_submit_window_update() can send
delta_window_size in [1, (1 << 31)-1], inclusive, without bounded by
stream's recv_window_size. Of course, the application is now
responsible to keep the resulting window size <= (1 << 31)-1.
spdylay_submit_window_update() now returns
SPDYLAY_ERR_INVALID_ARGUMENT if delta_window_size is 0 or negative.
The spdylay_data contains full of implementation details and is not
used in public API. It should be hidden.
The spdylay_frame union now only contains the control frame.
Made spdylay_session_get_pri_lowest() to get the lowest priority value
for the current session.
This change allows the application code to get the lowest priority value
without knowing the protocol version which the current session uses.
We say the header block is invalid if at least one of the following
condition is true:
There are duplicate header names; or the header names are not
encoded in US-ASCII character set and not lower cased; or the
header name is zero-length string; or the header value contains
multiple in-sequence NUL bytes.
spdylay_frame_unpack_nv() returns SPDYLAY_ERR_INVALID_HEADER_BLOCK
if the unpacking suceeded but it found the header block is invalid.
This means that caller treats it as success, but do additional
processing for invalid header block if it wants.
The functions calling spdylay_frame_unpack_nv() also return
SPDYLAY_ERR_INVALID_HEADER_BLOCK.
spdylay_session_mem_recv() processes input bytes as the received data
from the remote endpoint. spdylay_session_recv() uses it internally.
The spdylay_inbound_buffer and ibuf member in spdylay_session is removed.
The buffer is allocated in the stack when spdylay_session_recv() is called.