aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_request.c
Commit message (Collapse)AuthorAge
* SNI: added restriction for TLSv1.3 cross-SNI session resumption.Sergey Kandaurov2025-02-05
| | | | | | | | | | | | | | | | | In OpenSSL, session resumption always happens in the default SSL context, prior to invoking the SNI callback. Further, unlike in TLSv1.2 and older protocols, SSL_get_servername() returns values received in the resumption handshake, which may be different from the value in the initial handshake. Notably, this makes the restriction added in b720f650b insufficient for sessions resumed with different SNI server name. Considering the example from b720f650b, previously, a client was able to request example.org by presenting a certificate for example.org, then to resume and request example.com. The fix is to reject handshakes resumed with a different server name, if verification of client certificates is enabled in a corresponding server configuration.
* Added "keepalive_min_timeout" directive.Roman Arutyunyan2025-02-05
| | | | | | | | | | | | | | | | | The directive sets a timeout during which a keepalive connection will not be closed by nginx for connection reuse or graceful shutdown. The change allows clients that send multiple requests over the same connection without delay or with a small delay between them, to avoid receiving a TCP RST in response to one of them. This excludes network issues and non-graceful shutdown. As a side-effect, it also addresses the TCP reset problem described in RFC 9112, Section 9.6, when the last sent HTTP response could be damaged by a followup TCP RST. It is important for non-idempotent requests, which cannot be retried by client. It is not recommended to set keepalive_min_timeout to large values as this can introduce an additional delay during graceful shutdown and may restrict nginx from effective connection reuse.
* SSL: caching certificates and certificate keys with variables.Sergey Kandaurov2025-01-17
| | | | | | | | A new directive "ssl_certificate_cache max=N [valid=time] [inactive=time]" enables caching of SSL certificate chain and secret key objects specified by "ssl_certificate" and "ssl_certificate_key" directives with variables. Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
* Fixed request termination with AIO and subrequests (ticket #2555).Maxim Dounin2024-01-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a request was terminated due to an error via ngx_http_terminate_request() while an AIO operation was running in a subrequest, various issues were observed. This happened because ngx_http_request_finalizer() was only set in the subrequest where ngx_http_terminate_request() was called, but not in the subrequest where the AIO operation was running. After completion of the AIO operation normal processing of the subrequest was resumed, leading to issues. In particular, in case of the upstream module, termination of the request called upstream cleanup, which closed the upstream connection. Attempts to further work with the upstream connection after AIO operation completion resulted in segfaults in ngx_ssl_recv(), "readv() failed (9: Bad file descriptor) while reading upstream" errors, or socket leaks. In ticket #2555, issues were observed with the following configuration with cache background update (with thread writing instrumented to introduce a delay, when a client closes the connection during an update): location = /background-and-aio-write { proxy_pass ... proxy_cache one; proxy_cache_valid 200 1s; proxy_cache_background_update on; proxy_cache_use_stale updating; aio threads; aio_write on; limit_rate 1000; } Similarly, the same issue can be seen with SSI, and can be caused by errors in subrequests, such as in the following configuration (where "/proxy" uses AIO, and "/sleep" returns 444 after some delay, causing request termination): location = /ssi-active-boom { ssi on; ssi_types *; return 200 ' <!--#include virtual="/proxy" --> <!--#include virtual="/sleep" --> '; limit_rate 1000; } Or the same with both AIO operation and the error in non-active subrequests (which needs slightly different handling, see below): location = /ssi-non-active-boom { ssi on; ssi_types *; return 200 ' <!--#include virtual="/static" --> <!--#include virtual="/proxy" --> <!--#include virtual="/sleep" --> '; limit_rate 1000; } Similarly, issues can be observed with just static files. However, with static files potential impact is limited due to timeout safeguards in ngx_http_writer(), and the fact that c->error is set during request termination. In a simple configuration with an AIO operation in the active subrequest, such as in the following configuration, the connection is closed right after completion of the AIO operation anyway, since ngx_http_writer() tries to write to the connection and fails due to c->error set: location = /ssi-active-static-boom { ssi on; ssi_types *; return 200 ' <!--#include virtual="/static-aio" --> <!--#include virtual="/sleep" --> '; limit_rate 1000; } In the following configuration, with an AIO operation in a non-active subrequest, the connection is closed only after send_timeout expires: location = /ssi-non-active-static-boom { ssi on; ssi_types *; return 200 ' <!--#include virtual="/static" --> <!--#include virtual="/static-aio" --> <!--#include virtual="/sleep" --> '; limit_rate 1000; } Fix is to introduce r->main->terminated flag, which is to be checked by AIO event handlers when the r->main->blocked counter is decremented. When the flag is set, handlers are expected to wake up the connection instead of the subrequest (which might be already cleaned up). Additionally, now ngx_http_request_finalizer() is always set in the active subrequest, so waking up the connection properly finalizes the request even if termination happened in a non-active subrequest.
* HTTP: uniform checks in ngx_http_alloc_large_header_buffer().Vladimir Khomutov2023-11-29
| | | | | | | | | | | | | | | | If URI is not fully parsed yet, some pointers are not set. As a result, the calculation of "new + (ptr - old)" expression is flawed. According to C11, 6.5.6 Additive operators, p.9: : When two pointers are subtracted, both shall point to elements : of the same array object, or one past the last element of the : array object Since "ptr" is not set, subtraction leads to undefined behaviour, because "ptr" and "old" are not in the same buffer (i.e. array objects). Prodded by GCC undefined behaviour sanitizer.
* HTTP: removed unused r->port_start and r->port_end.Vladimir Khomutov2023-11-28
| | | | | | | | Neither r->port_start nor r->port_end were ever used. The r->port_end is set by the parser, though it was never used by the following code (and was never usable, since not copied by the ngx_http_alloc_large_header_buffer() without r->port_start set).
* SSL: removed the "ssl" directive.Roman Arutyunyan2023-06-08
| | | | | | It has been deprecated since 7270:46c0c7ef4913 (1.15.0) in favour of the "ssl" parameter of the "listen" directive, which has been available since 2224:109849282793 (0.7.14).
* HTTP/2: "http2" directive.Roman Arutyunyan2023-05-16
| | | | | | | | | | | | | | | | The directive enables HTTP/2 in the current server. The previous way to enable HTTP/2 via "listen ... http2" is now deprecated. The new approach allows to share HTTP/2 and HTTP/0.9-1.1 on the same port. For SSL connections, HTTP/2 is now selected by ALPN callback based on whether the protocol is enabled in the virtual server chosen by SNI. This however only works since OpenSSL 1.0.2h, where ALPN callback is invoked after SNI callback. For older versions of OpenSSL, HTTP/2 is enabled based on the default virtual server configuration. For plain TCP connections, HTTP/2 is now auto-detected by HTTP/2 preface, if HTTP/2 is enabled in the default virtual server. If preface is not matched, HTTP/0.9-1.1 is assumed.
* Merged with the default branch.Sergey Kandaurov2023-03-29
|\
| * Lingering close for connections with pipelined requests.Maxim Dounin2023-02-02
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is expected to help with clients using pipelining with some constant depth, such as apt[1][2]. When downloading many resources, apt uses pipelining with some constant depth, a number of requests in flight. This essentially means that after receiving a response it sends an additional request to the server, and this can result in requests arriving to the server at any time. Further, additional requests are sent one-by-one, and can be easily seen as such (neither as pipelined, nor followed by pipelined requests). The only safe approach to close such connections (for example, when keepalive_requests is reached) is with lingering. To do so, now nginx monitors if pipelining was used on the connection, and if it was, closes the connection with lingering. [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=973861#10 [2] https://mailman.nginx.org/pipermail/nginx-devel/2023-January/ZA2SP5SJU55LHEBCJMFDB2AZVELRLTHI.html
* | HTTP/3: "quic" parameter of "listen" directive.Roman Arutyunyan2023-02-27
| | | | | | | | | | | | | | | | | | Now "listen" directve has a new "quic" parameter which enables QUIC protocol for the address. Further, to enable HTTP/3, a new directive "http3" is introduced. The hq-interop protocol is enabled by "http3_hq" as before. Now application protocol is chosen by ALPN. Previously used "http3" parameter of "listen" is deprecated.
* | HTTP/3: renamed functions.Roman Arutyunyan2022-08-22
| | | | | | | | | | ngx_http_v3_init() is renamed ngx_http_v3_init_stream(). ngx_http_v3_reset_connection() is renamed to ngx_http_v3_reset_stream().
* | Merged with the default branch.Sergey Kandaurov2022-06-22
|\|
| * All non-unique input headers are now linked lists.Maxim Dounin2022-05-30
| | | | | | | | | | | | The ngx_http_process_multi_header_lines() function is removed, as it is exactly equivalent to ngx_http_process_header_line(). Similarly, ngx_http_variable_header() is used instead of ngx_http_variable_headers().
| * Reworked multi headers to use linked lists.Maxim Dounin2022-05-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multi headers are now using linked lists instead of arrays. Notably, the following fields were changed: r->headers_in.cookies (renamed to r->headers_in.cookie), r->headers_in.x_forwarded_for, r->headers_out.cache_control, r->headers_out.link, u->headers_in.cache_control u->headers_in.cookies (renamed to u->headers_in.set_cookie). The r->headers_in.cookies and u->headers_in.cookies fields were renamed to r->headers_in.cookie and u->headers_in.set_cookie to match header names. The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines() functions were changed accordingly. With this change, multi headers are now essentially equivalent to normal headers, and following changes will further make them equivalent.
| * Perl: fixed $r->header_in("Connection").Maxim Dounin2022-05-30
| | | | | | | | | | | | Previously, the r->header_in->connection pointer was never set despite being present in ngx_http_headers_in, resulting in incorrect value returned by $r->header_in("Connection") in embedded perl.
* | HTTP/3: set c->error on read error in ngx_http_test_reading().Roman Arutyunyan2022-01-12
| | | | | | | | Similar to other error/eof cases.
* | HTTP/3: simplified code.Roman Arutyunyan2022-01-12
| |
* | QUIC: fixed e06283038ec8 mis-merge.Sergey Kandaurov2021-12-09
| | | | | | | | The NGX_HTTP_QUIC macro was removed in 33226ac61076.
* | QUIC: clear SSL_OP_ENABLE_MIDDLEBOX_COMPAT on SSL context switch.Sergey Kandaurov2021-12-07
| | | | | | | | | | | | | | | | | | | | | | | | The SSL_OP_ENABLE_MIDDLEBOX_COMPAT option is provided by QuicTLS and enabled by default in the newly created SSL contexts. SSL_set_quic_method() is used to clear it, which is required for SSL handshake to work on QUIC connections. Switching context in the ngx_http_ssl_servername() SNI callback overrides SSL options from the new SSL context. This results in the option set again. Fix is to explicitly clear it when switching to another SSL context. Initially reported here (in Russian): http://mailman.nginx.org/pipermail/nginx-ru/2021-November/063989.html
* | HTTP/3: http3_hq directive and NGX_HTTP_V3_HQ macro.Roman Arutyunyan2021-12-04
| | | | | | | | Listen quic parameter is no longer supported.
* | HTTP/3: merged ngx_http_quic_module into ngx_http_v3_module.Roman Arutyunyan2021-12-06
| |
* | HTTP/3: allowed QUIC stream connection reuse.Roman Arutyunyan2021-10-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A QUIC stream connection is treated as reusable until first bytes of request arrive, which is also when the request object is now allocated. A connection closed as a result of draining, is reset with the error code H3_REQUEST_REJECTED. Such behavior is allowed by quic-http-34: Once a request stream has been opened, the request MAY be cancelled by either endpoint. Clients cancel requests if the response is no longer of interest; servers cancel requests if they are unable to or choose not to respond. When the server cancels a request without performing any application processing, the request is considered "rejected." The server SHOULD abort its response stream with the error code H3_REQUEST_REJECTED. The client can treat requests rejected by the server as though they had never been sent at all, thereby allowing them to be retried later.
* | Merged with the default branch.Sergey Kandaurov2021-11-03
|\|
| * SSL: SSL_sendfile() support with kernel TLS.Maxim Dounin2021-10-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Requires OpenSSL 3.0 compiled with "enable-ktls" option. Further, KTLS needs to be enabled in kernel, and in OpenSSL, either via OpenSSL configuration file or with "ssl_conf_command Options KTLS;" in nginx configuration. On FreeBSD, kernel TLS is available starting with FreeBSD 13.0, and can be enabled with "sysctl kern.ipc.tls.enable=1" and "kldload ktls_ocf" to load a software backend, see man ktls(4) for details. On Linux, kernel TLS is available starting with kernel 4.13 (at least 5.2 is recommended), and needs kernel compiled with CONFIG_TLS=y (with CONFIG_TLS=m, which is used at least on Ubuntu 21.04 by default, the tls module needs to be loaded with "modprobe tls").
| * HTTP/2: removed support for NPN.Vladimir Homutov2021-10-15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | NPN was replaced with ALPN, published as RFC 7301 in July 2014. It used to negotiate SPDY (and, in transition, HTTP/2). NPN supported appeared in OpenSSL 1.0.1. It does not work with TLSv1.3 [1]. ALPN is supported since OpenSSL 1.0.2. The NPN support was dropped in Firefox 53 [2] and Chrome 51 [3]. [1] https://github.com/openssl/openssl/issues/3665. [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1248198 [3] https://www.chromestatus.com/feature/5767920709795840
* | HTTP/3: reset streams with incomplete responses or timeouts.Roman Arutyunyan2021-09-27
| | | | | | | | | | This prevents client from closing the QUIC connection due to response parse error.
* | HTTP/3: fixed segfault when using SSL certificates with variables.Sergey Kandaurov2021-09-29
| | | | | | | | | | | | | | | | | | | | | | | | A QUIC connection doesn't have c->log->data and friends initialized to sensible values. Yet, a request can be created in the certificate callback with such an assumption, which leads to a segmentation fault due to null pointer dereference in ngx_http_free_request(). The fix is to adjust initializing the QUIC part of a connection such that it has all of that in place. Further, this appends logging error context for unsuccessful QUIC handshakes: - cannot load certificate .. while handling frames - SSL_do_handshake() failed .. while sending frames
* | HTTP/3: make ngx_http_log_error() static again.Roman Arutyunyan2021-09-17
| | | | | | | | | | | | | | | | This function was only referenced from ngx_http_v3_create_push_request() to initialize push connection log. Now the log handler is copied from the parent request connection. The change reduces diff to the default branch.
* | Merged with the default branch.Sergey Kandaurov2021-09-01
|\|
| * Disabled HTTP/1.0 requests with Transfer-Encoding.Sergey Kandaurov2021-08-09
| | | | | | | | | | | | | | | | | | | | The latest HTTP/1.1 draft describes Transfer-Encoding in HTTP/1.0 as having potentially faulty message framing as that could have been forwarded without handling of the chunked encoding, and forbids processing subsequest requests over that connection: https://github.com/httpwg/http-core/issues/879. While handling of such requests is permitted, the most secure approach seems to reject them.
* | Merged with the default branch.Sergey Kandaurov2021-07-15
|\|
| * Disabled control characters in the Host header.Maxim Dounin2021-06-28
| | | | | | | | | | | | Control characters (0x00-0x1f, 0x7f) and space are not expected to appear in the Host header. Requests with such characters in the Host header are now unconditionally rejected.
| * Improved logging of invalid headers.Maxim Dounin2021-06-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | In 71edd9192f24 logging of invalid headers which were rejected with the NGX_HTTP_PARSE_INVALID_HEADER error was restricted to just the "client sent invalid header line" message, without any attempts to log the header itself. This patch returns logging of the header up to the invalid character and the character itself. The r->header_end pointer is now properly set in all cases to make logging possible. The same logging is also introduced when parsing headers from upstream servers.
| * Disabled spaces in URIs (ticket #196).Maxim Dounin2021-06-28
| | | | | | | | | | | | | | From now on, requests with spaces in URIs are immediately rejected rather than allowed. Spaces were allowed in 31e9677b15a1 (0.8.41) to handle bad clients. It is believed that now this behaviour causes more harm than good.
| * Disabled requests with both Content-Length and Transfer-Encoding.Maxim Dounin2021-06-28
| | | | | | | | | | | | | | | | HTTP clients are not allowed to generate such requests since Transfer-Encoding introduction in RFC 2068, and they are not expected to appear in practice except in attempts to perform a request smuggling attack. While handling of such requests is strictly defined, the most secure approach seems to reject them.
| * Added CONNECT method rejection.Maxim Dounin2021-06-28
| | | | | | | | | | | | | | | | | | No valid CONNECT requests are expected to appear within nginx, since it is not a forward proxy. Further, request line parsing will reject proper CONNECT requests anyway, since we don't allow authority-form of request-target. On the other hand, RFC 7230 specifies separate message length rules for CONNECT which we don't support, so make sure to always reject CONNECTs to avoid potential abuse.
| * Moved TRACE method rejection to a better place.Maxim Dounin2021-06-28
| | | | | | | | | | | | | | Previously, TRACE requests were rejected before parsing Transfer-Encoding. This is not important since keepalive is not enabled at this point anyway, though rejecting such requests after properly parsing other headers is less likely to cause issues in case of further code changes.
| * Fixed SSL logging with lingering close.Maxim Dounin2021-06-01
| | | | | | | | | | | | | | | | | | | | Recent fixes to SSL shutdown with lingering close (554c6ae25ffc, 1.19.5) broke logging of SSL variables. To make sure logging of SSL variables works properly, avoid freeing c->ssl when doing an SSL shutdown before lingering close. Reported by Reinis Rozitis (http://mailman.nginx.org/pipermail/nginx/2021-May/060670.html).
* | Merged with the default branch.Sergey Kandaurov2021-05-28
|\|
| * Fixed log action when using SSL certificates with variables.Maxim Dounin2021-05-24
| | | | | | | | | | | | | | | | | | | | When variables are used in ssl_certificate or ssl_certificate_key, a request is created in the certificate callback to evaluate the variables, and then freed. Freeing it, however, updates c->log->action to "closing request", resulting in confusing error messages like "client timed out ... while closing request" when a client times out during the SSL handshake. Fix is to restore c->log->action after calling ngx_http_free_request().
* | Merged with the default branch.Sergey Kandaurov2021-03-30
|\|
| * Cancel keepalive and lingering close on EOF better (ticket #2145).Sergey Kandaurov2021-03-24
| | | | | | | | | | | | | | | | | | | | | | Unlike in 75e908236701, which added the logic to ngx_http_finalize_request(), this change moves it to a more generic routine ngx_http_finalize_connection() to cover cases when a request is finalized with NGX_DONE. In particular, this fixes unwanted connection transition into the keepalive state after receiving EOF while discarding request body. With edge-triggered event methods that means the connection will last for extra seconds as set in the keepalive_timeout directive.
* | Merged with the default branch.Sergey Kandaurov2021-02-17
|\|
| * Reuse of connections in lingering close.Maxim Dounin2021-02-11
| | | | | | | | | | | | | | | | | | | | | | | | 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.
| * Core: removed post_accept_timeout.Maxim Dounin2021-01-19
| | | | | | | | | | | | | | | | | | | | Keeping post_accept_timeout in ngx_listening_t is no longer needed since we've switched to 1 second timeout for deferred accept in 5541:fdb67cfc957d. Further, using it in HTTP code can result in client_header_timeout being used from an incorrect server block, notably if address-specific virtual servers are used along with a wildcard listening socket, or if we've switched to a different server block based on SNI in SSL handshake.
* | HTTP/3: removed HTTP/3-specific code.Roman Arutyunyan2020-12-21
| | | | | | | | | | | | The ngx_http_set_lingering_close() function is not called for HTTP/3. The change reduces diff to the default branch.
* | HTTP/3: refactored request parser.Roman Arutyunyan2021-01-22
| | | | | | | | | | The change reduces diff to the default branch for src/http/ngx_http_request.c and src/http/ngx_http_parse.c.
* | Merged with the default branch.Sergey Kandaurov2020-12-15
|\|
| * Removed extra allocation for r->uri.Maxim Dounin2020-12-10
| | | | | | | | | | | | | | The ngx_http_parse_complex_uri() function cannot make URI longer and does not null-terminate URI, so there is no need to allocate an extra byte. This allocation appears to be a leftover from changes in 461:a88a3e4e158f (0.1.5), where null-termination of r->uri and many other strings was removed.