summaryrefslogtreecommitdiffhomepage
path: root/src/http/v2 (follow)
AgeCommit message (Collapse)AuthorFilesLines
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.
2018-02-15HTTP/2: push additional request headers (closes #1478).Ruslan Ermilov3-94/+214
The Accept-Encoding, Accept-Language, and User-Agent header fields are now copied from the original request to pushed requests.
2018-02-15HTTP/2: style.Sergey Kandaurov2-4/+4
2018-02-09HTTP/2: fixed null pointer dereference with server push.Ruslan Ermilov1-1/+5
r->headers_in.host can be NULL in ngx_http_v2_push_resource(). This happens when a request is terminated with 400 before the :authority or Host header is parsed, and either pushing is enabled on the server{} level or error_page 400 redirects to a location with pushes configured. Found by Coverity (CID 1429156).
2018-02-08HTTP/2: fixed build with -Werror=unused-but-set-variable.Ruslan Ermilov1-10/+3
2018-02-08HTTP/2: server push.Ruslan Ermilov5-18/+873
Resources to be pushed are configured with the "http2_push" directive. Also, preload links from the Link response headers, as described in https://www.w3.org/TR/preload/#server-push-http-2, can be pushed, if enabled with the "http2_push_preload" directive. Only relative URIs with absolute paths can be pushed. The number of concurrent pushes is normally limited by a client, but cannot exceed a hard limit set by the "http2_max_concurrent_pushes" directive.
2018-02-08HTTP/2: changed prototypes of request pseudo-headers parsers.Ruslan Ermilov1-25/+24
No functional changes.
2018-02-06HTTP/2: removed unused field from ngx_http_v2_stream_t.Sergey Kandaurov1-2/+0
2018-01-30HTTP/2: finalize request as bad if parsing of pseudo-headers fails.Ruslan Ermilov1-8/+1
This is in line when the required pseudo-headers are missing, and avoids spurious zero statuses in access.log.
2018-01-29HTTP/2: more style, comments, and debugging.Ruslan Ermilov3-158/+168
2018-01-29HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.Ruslan Ermilov1-2/+2
2017-10-04HTTP/2: enforce writing the sync request body buffer to file.Valentin Bartenev1-5/+2
The sync flag of HTTP/2 request body buffer is used when the size of request body is unknown or bigger than configured "client_body_buffer_size". In this case the buffer points to body data inside the global receive buffer that is used for reading all HTTP/2 connections in the worker process. Thus, when the sync flag is set, the buffer must be flushed to a temporary file, otherwise the request body data can be overwritten. Previously, the sync buffer wasn't flushed to a temporary file if the whole body was received in one DATA frame with the END_STREAM flag and wasn't copied into the HTTP/2 body preread buffer. As a result, the request body might be corrupted (ticket #1384). Now, setting r->request_body_in_file_only enforces writing the sync buffer to a temporary file in all cases.
2017-09-14HTTP/2: shortened some debug log messages.Maxim Dounin3-8/+8
This ensures slightly more readable debug logs on 80-character-wide terminals.
2017-09-14HTTP/2: fixed debug log about indexed headers.Maxim Dounin1-1/+1
Previously, "get indexed header" message was logged when in fact only header name was obtained using an index, and "get indexed header name" was logged when full header representation (name and value) was obtained using an index. Fixed version logs "get indexed name" and "get indexed header" respectively.
2017-09-14HTTP/2: added logging of 400 (Bad Request) reasons.Maxim Dounin1-0/+13
2017-08-30HTTP/2: signal 0-byte HPACK's dynamic table size.Piotr Sikora3-1/+16
This change lets NGINX talk to clients with SETTINGS_HEADER_TABLE_SIZE smaller than the default 4KB. Previously, NGINX would ACK the SETTINGS frame with a small dynamic table size, but it would never send dynamic table size update, leading to a connection-level COMPRESSION_ERROR. Also, it allows clients to release 4KB of memory per connection, since NGINX doesn't use HPACK's dynamic table when encoding headers, however clients had to maintain it, since NGINX never signaled that it doesn't use it. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-08-01Variables: macros for null variables.Ruslan Ermilov1-1/+1
No functional changes.
2017-03-24HTTP/2: added support for trailers in HTTP responses.Piotr Sikora1-14/+152
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-06-13HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header.Piotr Sikora1-0/+1
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-06-02HTTP/2: don't send SETTINGS ACK before already queued DATA frames.Piotr Sikora2-1/+10
Previously, SETTINGS ACK was sent immediately upon receipt of SETTINGS frame, before already queued DATA frames created using old SETTINGS. This incorrect behavior was source of interoperability issues, because peers rely on the fact that new SETTINGS are in effect after receiving SETTINGS ACK. Reported by Feng Li. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-06-02HTTP/2: make SETTINGS ACK frame reusable.Piotr Sikora1-25/+31
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
2017-06-02HTTP/2: send SETTINGS ACK after applying all SETTINGS params.Piotr Sikora1-2/+2
This avoids sending unnecessary SETTINGS ACK in case of PROTOCOL_ERROR. Signed-off-by: Piotr Sikora <piotrsikora@google.com>