Commit Graph

127 Commits

Author SHA1 Message Date
Valentin Bartenev
74ee55ec1b HTTP/2: support for unbuffered upload of request body. 2016-04-01 15:57:10 +03:00
Valentin Bartenev
948eeca222 HTTP/2: rewritten handling of request body.
There are two improvements:

  1. Support for request body filters;

  2. Receiving of request body is started only after
     the ngx_http_read_client_request_body() call.

The last one fixes the problem when the client_max_body_size value might not be
respected from the right location if the location was changed either during the
process of receiving body or after the whole body had been received.
2016-04-01 15:56:03 +03:00
Valentin Bartenev
cedba685a1 HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.
RFC 7540 states that "A server can send a complete response prior to the client
sending an entire request if the response does not depend on any portion of the
request that has not been sent and received.  When this is true, a server MAY
request that the client abort transmission of a request without error by sending
a RST_STREAM with an error code of NO_ERROR after sending a complete response
(i.e., a frame with the END_STREAM flag)."

This should prevent a client from blocking on the stream window, since it isn't
maintained for closed streams.  Currently, quite big initial stream windows are
used, so such blocking is very unlikly, but that will be changed in the further
patches.
2016-04-01 15:56:03 +03:00
Sergey Kandaurov
00ef9ff5f0 Fixed logging. 2016-03-31 02:33:57 +03:00
Valentin Bartenev
ae5e76ea06 HTTP/2: improved debugging of sending control frames. 2016-03-21 17:04:21 +03:00
Valentin Bartenev
f72bcf8285 HTTP/2: implemented per request timeouts (closes #626).
Previously, there were only three timeouts used globally for the whole HTTP/2
connection:

 1. Idle timeout for inactivity when there are no streams in processing
    (the "http2_idle_timeout" directive);

 2. Receive timeout for incomplete frames when there are no streams in
    processing (the "http2_recv_timeout" directive);

 3. Send timeout when there are frames waiting in the output queue
    (the "send_timeout" directive on a server level).

Reaching one of these timeouts leads to HTTP/2 connection close.

This left a number of scenarios when a connection can get stuck without any
processing and timeouts:

 1. A client has sent the headers block partially so nginx starts processing
    a new stream but cannot continue without the rest of HEADERS and/or
    CONTINUATION frames;

 2. When nginx waits for the request body;

 3. All streams are stuck on exhausted connection or stream windows.

The first idea that was rejected was to detect when the whole connection
gets stuck because of these situations and set the global receive timeout.
The disadvantage of such approach would be inconsistent behaviour in some
typical use cases.  For example, if a user never replies to the browser's
question about where to save the downloaded file, the stream will be
eventually closed by a timeout.  On the other hand, this will not happen
if there's some activity in other concurrent streams.

Now almost all the request timeouts work like in HTTP/1.x connections, so
the "client_header_timeout", "client_body_timeout", and "send_timeout" are
respected.  These timeouts close the request.

The global timeouts work as before.

Previously, the c->write->delayed flag was abused to avoid setting timeouts on
stream events.  Now, the "active" and "ready" flags are manipulated instead to
control the processing of individual streams.
2016-02-24 15:58:07 +03:00
Valentin Bartenev
4e6a490fa7 HTTP/2: always use temporary pool for processing headers.
This is required for implementing per request timeouts.

Previously, the temporary pool was used only during skipping of
headers and the request pool was used otherwise.  That required
switching of pools if the request was closed while parsing.

It wasn't a problem since the request could be closed only after
the validation of the fully parsed header.  With the per request
timeouts, the request can be closed at any moment, and switching
of pools in the middle of parsing header name or value becomes a
problem.

To overcome this, the temporary pool is now always created and
used.  Special checks are added to keep it when either the stream
is being processed or until header block is fully parsed.
2016-02-24 16:05:47 +03:00
Valentin Bartenev
8b40f1eaec HTTP/2: cleaned up state while closing stream.
Without this the state might keep pointing to already closed stream.
2016-02-24 16:05:46 +03:00
Valentin Bartenev
cb173ff672 HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION. 2016-02-02 16:33:55 +03:00
Valentin Bartenev
8050277acf HTTP/2: fixed request length accounting.
Now it includes not only the received body size,
but the size of headers block as well.
2016-02-02 16:33:55 +03:00
Valentin Bartenev
405f4f99b4 HTTP/2: fixed excessive memory allocation for pool cleanup. 2016-02-02 16:33:55 +03:00
Ruslan Ermilov
362fb6c1d4 Stop emulating a space character after r->method_name.
This is an API change.

The proxy module was modified to not depend on this in 44122bddd9a1.
No known third-party modules seem to depend on this.
2015-11-30 12:54:01 +03:00
Valentin Bartenev
8323cd693b HTTP/2: fixed invalid headers handling (ticket #831).
The r->invalid_header flag wasn't reset once an invalid header appeared in a
request, resulting in all subsequent headers in the request were also marked
as invalid.
2015-11-13 20:10:50 +03:00
Valentin Bartenev
b22c0e0846 HTTP/2: backed out 16905ecbb49e (ticket #822).
It caused inconsistency between setting "in_closed" flag and the moment when
the last DATA frame was actually read.  As a result, the body buffer might not
be initialized properly in ngx_http_v2_init_request_body(), which led to a
segmentation fault in ngx_http_v2_state_read_data().  Also it might cause
start processing of incomplete body.

This issue could be triggered when the processing of a request was delayed,
e.g. in the limit_req or auth_request modules.
2015-11-05 15:01:01 +03:00
Valentin Bartenev
090c471032 HTTP/2: changed behavior of the "http2_max_field_size" directive.
Now it limits only the maximum length of literal string (either raw or
compressed) in HPACK request header fields.  It's easier to understand
and to describe in the documentation.
2015-10-27 23:16:35 +03:00
Valentin Bartenev
edf30961e6 HTTP/2: fixed spelling. 2015-10-27 23:16:35 +03:00
Valentin Bartenev
f36f51725a HTTP/2: simplified checking the END_STREAM flag.
No functional changes.
2015-10-26 17:46:28 +03:00
Piotr Sikora
f93aa4d953 HTTP/2: fix handling of connection errors.
Previously, nginx worker would crash because of a double free
if client disconnected or timed out before sending all headers.

Found with afl-fuzz.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2015-10-01 20:25:55 -07:00
Piotr Sikora
de4f0eb26b HTTP/2: fix indirect reprioritization.
Previously, streams that were indirectly reprioritized (either because of
a new exclusive dependency on their parent or because of removal of their
parent from the dependency tree), didn't have their pointer to the parent
node updated.

This broke detection of circular dependencies and, as a result, nginx
worker would crash due to stack overflow whenever such dependency was
introduced.

Found with afl-fuzz.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2015-10-01 20:25:55 -07:00
Piotr Sikora
71a6b600c2 HTTP/2: reject self-dependent streams.
Per RFC7540, a stream cannot depend on itself.

Previously, this requirement was enforced on PRIORITY frames, but not on
HEADERS frames and due to the implementation details nginx worker would
crash (stack overflow) while opening self-dependent stream.

Found with afl-fuzz.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2015-10-01 20:25:55 -07:00
Valentin Bartenev
c0eb2f0759 HTTP/2: improved error handling while parsing integers.
The case when an integer is out of frame bounds should be checked first
as a more accurate error.
2015-10-20 21:28:38 +03:00
Ruslan Ermilov
c830cf28ae HTTP/2: improved HPACK integer parsing code readability.
No functional changes.
2015-10-20 21:26:38 +03:00
Valentin Bartenev
7d2af13f3a HTTP/2: fixed parsing of literal header fields without indexing. 2015-10-19 16:16:47 +03:00
Valentin Bartenev
20669d1949 HTTP/2: fixed $server_protocol value (ticket #800). 2015-09-28 20:02:05 +03:00
Valentin Bartenev
61e1f16d90 HTTP/2: fixed header block parsing with CONTINUATION frames (#792).
It appears that the CONTINUATION frames don't need to be aligned to bounds of
individual headers.
2015-09-22 01:40:04 +03:00
Valentin Bartenev
a27d0bd00d HTTP/2: fixed HPACK header field parsing. 2015-09-22 01:40:04 +03:00
Valentin Bartenev
ee37ff613f The HTTP/2 implementation (RFC 7240, 7241).
The SPDY support is removed, as it's incompatible with the new module.
2015-09-11 20:13:06 +03:00