summaryrefslogtreecommitdiffhomepage
path: root/src/http/v2 (follow)
AgeCommit message (Collapse)AuthorFilesLines
2021-04-08Introduced the "keepalive_time" directive.Maxim Dounin1-1/+3
Similar to lingering_time, it limits total connection lifetime before keepalive is switched off. The default is 1 hour, which is close to the total maximum connection lifetime possible with default keepalive_requests and keepalive_timeout.
2021-04-07HTTP/2: relaxed PRIORITY frames limit.Maxim Dounin1-1/+1
Firefox uses several idle streams for PRIORITY frames[1], and "http2_max_concurrent_streams 1;" results in "client sent too many PRIORITY frames" errors when a connection is established by Firefox. Fix is to relax the PRIORITY frames limit to use at least 100 as the initial value (which is the recommended by the HTTP/2 protocol minimum limit on the number of concurrent streams, so it is not unreasonable for clients to assume that similar number of idle streams can be used for prioritization). [1] https://hg.mozilla.org/mozilla-central/file/32a9e6e145d6e3071c3993a20bb603a2f388722b/netwerk/protocol/http/Http2Stream.cpp#l1270
2021-03-26HTTP/2: improved handling of "keepalive_timeout 0".Maxim Dounin1-1/+3
Without explicit handling, a zero timer was actually added, leading to multiple unneeded syscalls. Further, sending GOAWAY frame early might be beneficial for clients. Reported by Sergey Kandaurov.
2021-03-01HTTP/2: client_header_timeout before first request (ticket #2142).Maxim Dounin1-2/+5
With this change, behaviour of HTTP/2 becomes even closer to HTTP/1.x, and client_header_timeout instead of keepalive_timeout is used before the first request is received. This fixes HTTP/2 connections being closed even before the first request if "keepalive_timeout 0;" was used in the configuration; the problem appeared in f790816a0e87 (1.19.7).
2021-02-11HTTP/2: removed http2_max_field_size and http2_max_header_size.Maxim Dounin3-29/+32
Instead, size of one large_client_header_buffers buffer and all large client header buffers are used.
2021-02-11HTTP/2: keepalive_timeout now armed once between requests.Maxim Dounin1-24/+15
Previously, PINGs and other frames extended possible keepalive time, making it possible to keep an open HTTP/2 connection for a long time. Now the connection is always closed as long as keepalive_timeout expires, similarly to how it happens in HTTP/1.x. Note that as a part of this change, incomplete frames are no longer trigger a separate timeout, so http2_recv_timeout (replaced by client_header_timeout in previous patches) is essentially cancelled. The client_header_timeout is, however, used for SSL handshake and while reading HEADERS frames.
2021-02-11HTTP/2: removed http2_idle_timeout and http2_max_requests.Maxim Dounin3-31/+39
Instead, keepalive_timeout and keepalive_requests are now used. This is expected to simplify HTTP/2 code and usage. This also matches directives used by upstream module for all protocols. In case of default settings, this effectively changes maximum number of requests per connection from 1000 to 100. This looks acceptable, especially given that HTTP/2 code now properly supports lingering close. Further, this changes default keepalive timeout in HTTP/2 from 300 seconds to 75 seconds. This also looks acceptable, and larger than PING interval used by Firefox (network.http.spdy.ping-threshold defaults to 58s), the only browser to use PINGs.
2021-02-11HTTP/2: removed http2_recv_timeout.Maxim Dounin3-14/+42
Instead, the client_header_timeout is now used for HTTP/2 reading. Further, the timeout is changed to be set once till no further data left to read, similarly to how client_header_timeout is used in other places.
2021-02-11HTTP/2: removed SPDY directives handling.Maxim Dounin1-69/+0
The spdy_* directives are not available since introduction of HTTP/2 module in nginx 1.9.5 more than five years ago.
2021-02-11HTTP/2: fixed reusing connections with active requests.Maxim Dounin1-0/+1
New connections are marked reusable by ngx_http_init_connection() if there are no data available for reading. As a result, if SSL is not used, ngx_http_v2_init() might be called when the connection is marked reusable. If a HEADERS frame is immediately available for reading, this resulted in connection being preserved in reusable state with an active request, and possibly closed later as if during worker shutdown (that is, after all active requests were finalized). Fix is to explicitly mark connections non-reusable in ngx_http_v2_init() instead of (incorrectly) assuming they are already non-reusable. Found by Sergey Kandaurov.
2021-02-11HTTP/2: reuse of connections with incomplete frames.Maxim Dounin1-1/+7
Prodded by Taewoo Kim.
2021-02-11Reuse of connections in lingering close.Maxim Dounin1-1/+4
This is particularly important in HTTP/2, where keepalive connections are closed with lingering. Before the patch, reusing a keepalive HTTP/2 connection resulted in the connection waiting for lingering close to remain in the reusable connections queue, preventing ngx_drain_connections() from closing additional connections. The patch fixes it by marking the connection reusable again, and so moving it in the reusable connections queue. Further, it makes actually possible to reuse such connections if needed.
2021-02-01HTTP/2: lingering close changed to handle NGX_AGAIN.Ruslan Ermilov1-0/+4
This part somehow slipped away from c5840ca2063d. While it is not expected to be needed in case of lingering close, it is good to keep it for correctness (see 2b5528023f6b).
2020-12-08SSL: fixed SSL shutdown on lingering close.Ruslan Ermilov1-2/+0
Ensure c->recv is properly reset to ngx_recv if SSL_shutdown() blocks on writing. The bug had appeared in 554c6ae25ffc.
2020-11-06SSL: fixed non-working SSL shutdown on lingering close.Ruslan Ermilov1-9/+33
When doing lingering close, the socket was first shut down for writing, so SSL shutdown initiated after lingering close was not able to send the close_notify alerts (ticket #2056). The fix is to call ngx_ssl_shutdown() before shutting down the socket.
2020-09-23HTTP/2: run posted requests after reading body.Maxim Dounin1-0/+4
HTTP/2 code failed to run posted requests after calling the request body handler, and this resulted in connection hang if a subrequest was created in the body handler and no other actions were made.
2020-09-23HTTP/2: fixed segfault on DATA frames after 400 errors.Maxim Dounin1-0/+7
If 400 errors were redirected to an upstream server using the error_page directive, DATA frames from the client might cause segmentation fault due to null pointer dereference. The bug had appeared in 6989:2c4dbcd6f2e4 (1.13.0). Fix is to skip such frames in ngx_http_v2_state_read_data() (similarly to 7561:9f1f9d6e056a). With the fix, behaviour of 400 errors in HTTP/2 is now similar to one in HTTP/1.x, that is, nginx doesn't try to read the request body. Note that proxying 400 errors, as well as other early stage errors, to upstream servers might not be a good idea anyway. These errors imply that reading and processing of the request (and the request headers) wasn't complete, and proxying of such incomplete request might lead to various errors. Reported by Chenglong Zhang.
2020-09-02HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.Sergey Kandaurov1-3/+31
Prodded by Xu Yang.
2020-08-10HTTP/2: fixed c->timedout flag on timed out connections.Maxim Dounin1-0/+1
Without the flag, SSL shutdown is attempted on such connections, resulting in useless work and/or bogus "SSL_shutdown() failed (SSL: ... bad write retry)" critical log messages if there are blocked writes.
2020-07-03HTTP/2: lingering close after GOAWAY.Ruslan Ermilov2-6/+124
After sending the GOAWAY frame, a connection is now closed using the lingering close mechanism. This allows for the reliable delivery of the GOAWAY frames, while also fixing connection resets observed when http2_max_requests is reached (ticket #1250), or with graceful shutdown (ticket #1544), when some additional data from the client is received on a fully closed connection. For HTTP/2, the settings lingering_close, lingering_timeout, and lingering_time are taken from the "server" level.
2020-05-25HTTP/2: invalid connection preface logging (ticket #1981).Maxim Dounin1-6/+4
Previously, invalid connection preface errors were only logged at debug level, providing no visible feedback, in particular, when a plain text HTTP/2 listening socket is erroneously used for HTTP/1.x connections. Now these are explicitly logged at the info level, much like other client-related errors.
2020-02-05HTTP/2: fixed socket leak with an incomplete HEADERS frame.Sergey Kandaurov1-2/+7
A connection could get stuck without timers if a client has partially sent the HEADERS frame such that it was split on the individual header boundary. In this case, it cannot be processed without the rest of the HEADERS frame. The fix is to call ngx_http_v2_state_headers_save() in this case. Normally, it would be called from the ngx_http_v2_state_header_block() handler on the next iteration, when there is not enough data to continue processing. This isn't the case if recv_buffer became empty and there's no more data to read.
2020-01-14HTTP/2: removed ngx_debug_point() call.Daniil Bondarev1-4/+0
     With the recent change to prevent frames flood in d4448892a294, nginx will finalize the connection with NGX_HTTP_V2_INTERNAL_ERROR whenever flood is detected, causing nginx aborting or stopping if the debug_points directive is used in nginx config.
2019-12-23HTTP/2: introduced separate handler to retry stream close.Maxim Dounin1-2/+19
When ngx_http_v2_close_stream_handler() is used to retry stream close after queued frames are sent, client timeouts on the stream can be logged multiple times and/or in addition to already happened errors. To resolve this, separate ngx_http_v2_retry_close_stream_handler() was introduced, which does not try to log timeouts.
2019-12-23HTTP/2: fixed socket leak with queued frames (ticket #1689).Maxim Dounin1-1/+2
If a stream is closed with queued frames, it is possible that no further write events will occur on the stream, leading to the socket leak. To fix this, the stream's fake connection read handler is set to ngx_http_v2_close_stream_handler(), to make sure that finalizing the connection with ngx_http_v2_finalize_connection() will be able to close the stream regardless of the current number of queued frames. Additionally, the stream's fake connection fc->error flag is explicitly set, so ngx_http_v2_handle_stream() will post a write event when queued frames are finally sent even if stream flow control window is exhausted.
2019-09-23HTTP/2: fixed worker_shutdown_timeout.Ruslan Ermilov1-0/+5
2019-09-23HTTP/2: fixed possible alert about left open socket on shutdown.Ruslan Ermilov1-3/+2
This could happen when graceful shutdown configured by worker_shutdown_timeout times out and is then followed by another timeout such as proxy_read_timeout. In this case, the HEADERS frame is added to the output queue, but attempt to send it fails (due to c->error forcibly set during graceful shutdown timeout). This triggers request finalization which attempts to close the stream. But the stream cannot be closed because there is a frame in the output queue, and the connection cannot be finalized. This leaves the connection open without any timer events leading to alert. The fix is to post write event when sending output queue fails on c->error. That will finalize the connection.
2019-09-18HTTP/2: traffic-based flood detection.Maxim Dounin3-3/+34
With this patch, all traffic over an HTTP/2 connection is counted in the h2c->total_bytes field, and payload traffic is counted in the h2c->payload_bytes field. As long as total traffic is many times larger than payload traffic, we consider this to be a flood.
2019-09-18HTTP/2: switched back to RST_STREAM with NO_ERROR.Maxim Dounin1-22/+0
In 8df664ebe037, we've switched to maximizing stream window instead of sending RST_STREAM. Since then handling of RST_STREAM with NO_ERROR was fixed at least in Chrome, hence we switch back to using RST_STREAM. This allows more effective rejecting of large bodies, and also minimizes non-payload traffic to be accounted in the next patch.
2019-09-10HTTP/2: close connection on zero WINDOW_UPDATE.Ruslan Ermilov1-33/+3
Don't waste server resources by sending RST_STREAM frames. Instead, reject WINDOW_UPDATE frames with invalid zero increment by closing connection with PROTOCOL_ERROR.
2019-09-10HTTP/2: close connection on frames with self-dependency.Ruslan Ermilov1-31/+9
Don't waste server resources by sending RST_STREAM frames. Instead, reject HEADERS and PRIORITY frames with self-dependency by closing connection with PROTOCOL_ERROR.
2019-08-19HTTP/2: discard remaining request body after redirect.Sergey Kandaurov1-2/+9
Previously, if unbuffered request body reading wasn't finished before the request was redirected to a different location using error_page or X-Accel-Redirect, and the request body is read again, this could lead to disastrous effects, such as a duplicate post_handler call or "http request count is zero" alert followed by a segmentation fault. This happened in the following configuration (ticket #1819): location / { proxy_request_buffering off; proxy_pass http://bad; proxy_intercept_errors on; error_page 502 = /error; } location /error { proxy_pass http://backend; }
2019-08-13HTTP/2: limited number of PRIORITY frames.Ruslan Ermilov2-0/+11
Fixed excessive CPU usage caused by a peer that continuously shuffles priority of streams. Fix is to limit the number of PRIORITY frames.
2019-08-13HTTP/2: limited number of DATA frames.Ruslan Ermilov3-5/+21
Fixed excessive memory growth and CPU usage if stream windows are manipulated in a way that results in generating many small DATA frames. Fix is to limit the number of simultaneously allocated DATA frames.
2019-08-13HTTP/2: reject zero length headers with PROTOCOL_ERROR.Sergey Kandaurov1-4/+8
Fixed uncontrolled memory growth if peer sends a stream of headers with a 0-length header name and 0-length header value. Fix is to reject headers with zero name length.
2019-07-18HTTP/2: return error on output on closed stream.Maxim Dounin1-0/+6
Without this, an (incorrect) output on a closed stream could result in a socket leak.
2018-11-06HTTP/2: limit the number of idle state switches.Ruslan Ermilov2-3/+11
An attack that continuously switches HTTP/2 connection between idle and active states can result in excessive CPU usage. This is because when a connection switches to the idle state, all of its memory pool caches are freed. This change limits the maximum allowed number of idle state switches to 10 * http2_max_requests (i.e., 10000 by default). This limits possible CPU usage in one connection, and also imposes a limit on the maximum lifetime of a connection. Initially reported by Gal Goldshtein from F5 Networks.
2018-11-06HTTP/2: flood detection.Ruslan Ermilov2-1/+12
Fixed uncontrolled memory growth in case peer is flooding us with some frames (e.g., SETTINGS and PING) and doesn't read data. Fix is to limit the number of allocated control frames.
2018-09-21Fixed socket leak with "return 444" in error_page (ticket #274).Maxim Dounin1-4/+14
Socket leak was observed in the following configuration: error_page 400 = /close; location = /close { return 444; } The problem is that "return 444" triggers termination of the request, and due to error_page termination thinks that it needs to use a posted request to clear stack. But at the early request processing where 400 errors are generated there are no ngx_http_run_posted_requests() calls, so the request is only terminated after an external event. Variants of the problem include "error_page 497" instead (ticket #695) and various other errors generated during early request processing (405, 414, 421, 494, 495, 496, 501, 505). The same problem can be also triggered with "return 499" and "return 408" as both codes trigger ngx_http_terminate_request(), much like "return 444". To fix this, the patch adds ngx_http_run_posted_requests() calls to ngx_http_process_request_line() and ngx_http_process_request_headers() functions, and to ngx_http_v2_run_request() and ngx_http_v2_push_stream() functions in HTTP/2. Since the ngx_http_process_request() function is now only called via other functions which call ngx_http_run_posted_requests(), the call there is no longer needed and was removed.
2018-08-09HTTP/2: workaround for clients which fail on table size updates.Maxim Dounin1-2/+5
There are clients which cannot handle HPACK's dynamic table size updates as added in 12cadc4669a7 (1.13.6). Notably, old versions of OkHttp library are known to fail on it (ticket #1397). This change makes it possible to work with such clients by only sending dynamic table size updates in response to SETTINGS_HEADER_TABLE_SIZE. As a downside, clients which do not use SETTINGS_HEADER_TABLE_SIZE will continue to maintain default 4k table.
2018-06-07HTTP/2: use scheme from original request for pushes (closes #1549).Ruslan Ermilov2-20/+19
Instead of the connection scheme, use scheme from the original request. This fixes pushes when SSL is terminated by a proxy server in front of nginx.
2018-06-07Added r->schema.Ruslan Ermilov1-9/+6
For HTTP/1, it keeps scheme from the absolute form of URI. For HTTP/2, the :scheme request pseudo-header field value.
2018-06-07HTTP/2: validate client request scheme.Ruslan Ermilov1-0/+23
The scheme is validated as per RFC 3986, Section 3.1.
2018-03-19HTTP/2: improved frame info debugging.Ruslan Ermilov2-5/+8
2018-03-17gRPC: special handling of "trailer only" responses.Maxim Dounin1-3/+6
The gRPC protocol makes a distinction between HEADERS frame with the END_STREAM flag set, and a HEADERS frame followed by an empty DATA frame with the END_STREAM flag. The latter is not permitted, and results in errors not being propagated through nginx. Instead, gRPC clients complain that "server closed the stream without sending trailers" (seen in grpc-go) or "13: Received RST_STREAM with error code 2" (seen in grpc-c). To fix this, nginx now returns HEADERS with the END_STREAM flag if the response length is known to be 0, and we are not expecting any trailer headers to be added. And the response length is explicitly set to 0 in the gRPC proxy if we see initial HEADERS frame with the END_STREAM flag set.
2018-03-17HTTP/2: externalized various constants and interfaces.Maxim Dounin5-91/+129
2018-03-05HTTP/2: unknown frames now logged at info level.Maxim Dounin1-2/+2
2018-02-22HTTP/2: style.Ruslan Ermilov1-17/+4
Unified the style of validity checks in ngx_http_v2_validate_header().
2018-02-15HTTP/2: precalculate hash for "Cookie".Maxim Dounin1-1/+2
There is no need to calculate hashes of static strings at runtime. The ngx_hash() macro can be used to do it during compilation instead, similarly to how it is done in ngx_http_proxy_module.c for "Server" and "Date" headers.
2018-02-15HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.Ruslan Ermilov1-15/+47
In particular, if a stream object allocation failed, and a client sent the PRIORITY frame for this stream, ngx_http_v2_set_dependency() could dereference a null pointer while trying to re-parent a dependency node.