summaryrefslogtreecommitdiffhomepage
path: root/src/http (unfollow)
AgeCommit message (Collapse)AuthorFilesLines
2022-01-11Avoid sending "Connection: keep-alive" when shutting down.Maxim Dounin1-0/+4
When a worker process is shutting down, keepalive is not used: this is checked before the ngx_http_set_keepalive() call in ngx_http_finalize_connection(). Yet the "Connection: keep-alive" header was still sent, even if we know that the worker process is shutting down, potentially resulting in additional requests being sent to the connection which is going to be closed anyway. While clients are expected to be able to handle asynchronous close events (see ticket #1022), it is certainly possible to send the "Connection: close" header instead, informing the client that the connection is going to be closed and potentially saving some unneeded work. With this change, we additionally check for worker process shutdown just before sending response headers, and disable keepalive accordingly.
2021-12-27Simplified sendfile(SF_NODISKIO) usage.Maxim Dounin1-82/+0
Starting with FreeBSD 11, there is no need to use AIO operations to preload data into cache for sendfile(SF_NODISKIO) to work. Instead, sendfile() handles non-blocking loading data from disk by itself. It still can, however, return EBUSY if a page is already being loaded (for example, by a different process). If this happens, we now post an event for the next event loop iteration, so sendfile() is retried "after a short period", as manpage recommends. The limit of the number of EBUSY tolerated without any progress is preserved, but now it does not result in an alert, since on an idle system event loop iteration might be very short and EBUSY can happen many times in a row. Instead, SF_NODISKIO is simply disabled for one call once the limit is reached. With this change, sendfile(SF_NODISKIO) is now used automatically as long as sendfile() is enabled, and no longer requires "aio on;".
2021-12-27Removed "aio sendfile", deprecated since 1.7.11.Maxim Dounin1-13/+0
2021-12-21Moved Huffman coding out of HTTP/2.Ruslan Ermilov7-43/+45
ngx_http_v2_huff_decode.c and ngx_http_v2_huff_encode.c are renamed to ngx_http_huff_decode.c and ngx_http_huff_encode.c.
2021-11-25HTTP/2: fixed sendfile() aio handling.Maxim Dounin3-10/+65
With sendfile() in threads ("aio threads; sendfile on;"), client connection can block on writing, waiting for sendfile() to complete. In HTTP/2 this might result in the request hang, since an attempt to continue processing in thread event handler will call request's write event handler, which is usually stopped by ngx_http_v2_send_chain(): it does nothing if there are no additional data and stream->queued is set. Further, HTTP/2 resets stream's c->write->ready to 0 if writing blocks, so just fixing ngx_http_v2_send_chain() is not enough. Can be reproduced with test suite on Linux with: TEST_NGINX_GLOBALS_HTTP="aio threads; sendfile on;" prove h2*.t The following tests currently fail: h2_keepalive.t, h2_priority.t, h2_proxy_max_temp_file_size.t, h2.t, h2_trailers.t. Similarly, sendfile() with AIO preloading on FreeBSD can block as well, with similar results. This is, however, harder to reproduce, especially on modern FreeBSD systems, since sendfile() usually does not return EBUSY. Fix is to modify ngx_http_v2_send_chain() so it actually tries to send data to the main connection when called, and to make sure that c->write->ready is set by the relevant event handlers.
2021-11-25HTTP/2: fixed "task already active" with sendfile in threads.Maxim Dounin2-2/+58
With sendfile in threads, "task already active" alerts might appear in logs if a write event happens on the main HTTP/2 connection, triggering a sendfile in threads while another thread operation is already running. Observed with "aio threads; aio_write on; sendfile on;" and with thread event handlers modified to post a write event to the main HTTP/2 connection (though can happen without any modifications). Similarly, sendfile() with AIO preloading on FreeBSD can trigger duplicate aio operation, resulting in "second aio post" alerts. This is, however, harder to reproduce, especially on modern FreeBSD systems, since sendfile() usually does not return EBUSY. Fix is to avoid starting a sendfile operation if other thread operation is active by checking r->aio in the thread handler (and, similarly, in aio preload handler). The added check also makes duplicate calls protection redundant, so it is removed.
2021-11-01SSL: $ssl_curve (ticket #2135).Sergey Kandaurov1-0/+3
The variable contains a negotiated curve used for the handshake key exchange process. Known curves are listed by their names, unknown ones are shown in hex. Note that for resumed sessions in TLSv1.2 and older protocols, $ssl_curve contains the curve used during the initial handshake, while in TLSv1.3 it contains the curve used during the session resumption (see the SSL_get_negotiated_group manual page for details). The variable is only meaningful when using OpenSSL 3.0 and above. With older versions the variable is empty.
2021-10-29Changed default value of sendfile_max_chunk to 2m.Maxim Dounin1-1/+1
The "sendfile_max_chunk" directive is important to prevent worker monopolization by fast connections. The 2m value implies maximum 200ms delay with 100 Mbps links, 20ms delay with 1 Gbps links, and 2ms on 10 Gbps links. It also seems to be a good value for disks.
2021-10-29Upstream: sendfile_max_chunk support.Maxim Dounin1-3/+6
Previously, connections to upstream servers used sendfile() if it was enabled, but never honored sendfile_max_chunk. This might result in worker monopolization for a long time if large request bodies are allowed.
2021-10-29Simplified sendfile_max_chunk handling.Maxim Dounin1-5/+1
Previously, it was checked that sendfile_max_chunk was enabled and almost whole sendfile_max_chunk was sent (see e67ef50c3176), to avoid delaying connections where sendfile_max_chunk wasn't reached (for example, when sending responses smaller than sendfile_max_chunk). Now we instead check if there are unsent data, and the connection is still ready for writing. Additionally we also check c->write->delayed to ignore connections already delayed by limit_rate. This approach is believed to be more robust, and correctly handles not only sendfile_max_chunk, but also internal limits of c->send_chain(), such as sendfile() maximum supported length (ticket #1870).
2021-10-29Switched to using posted next events after sendfile_max_chunk.Maxim Dounin1-2/+1
Previously, 1 millisecond delay was used instead. In certain edge cases this might result in noticeable performance degradation though, notably on Linux with typical CONFIG_HZ=250 (so 1ms delay becomes 4ms), sendfile_max_chunk 2m, and link speed above 2.5 Gbps. Using posted next events removes the artificial delay and makes processing fast in all cases.
2021-10-28Mp4: mp4_start_key_frame directive.Roman Arutyunyan1-27/+194
The directive enables including all frames from start time to the most recent key frame in the result. Those frames are removed from presentation timeline using mp4 edit lists. Edit lists are currently supported by popular players and browsers such as Chrome, Safari, QuickTime and ffmpeg. Among those not supporting them properly is Firefox[1]. Based on a patch by Tracey Jaquith, Internet Archive. [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1735300
2021-10-28Mp4: added ngx_http_mp4_update_mdhd_atom() function.Roman Arutyunyan1-8/+32
The function updates the duration field of mdhd atom. Previously it was updated in ngx_http_mp4_read_mdhd_atom(). The change makes it possible to alter track duration as a result of processing track frames.
2021-10-21SSL: SSL_sendfile() support with kernel TLS.Maxim Dounin2-4/+6
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").
2021-10-20HTTP: connections with wrong ALPN protocols are now rejected.Vladimir Homutov1-7/+6
This is a recommended behavior by RFC 7301 and is useful for mitigation of protocol confusion attacks [1]. To avoid possible negative effects, list of supported protocols was extended to include all possible HTTP protocol ALPN IDs registered by IANA [2], i.e. "http/1.0" and "http/0.9". [1] https://alpaca-attack.com/ [2] https://www.iana.org/assignments/tls-extensiontype-values/
2021-10-14SSL: added $ssl_alpn_protocol variable.Vladimir Homutov1-0/+3
The variable contains protocol selected by ALPN during handshake and is empty otherwise.
2021-10-15HTTP/2: removed support for NPN.Vladimir Homutov4-72/+9
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
2021-10-18Upstream: fixed logging level of upstream invalid header errors.Maxim Dounin4-4/+4
In b87b7092cedb (nginx 1.21.1), logging level of "upstream sent invalid header" errors was accidentally changed to "info". This change restores the "error" level, which is a proper logging level for upstream-side errors.
2021-10-12Synced ngx_http_subrequest() argument names (ticket #2255).Maxim Dounin1-2/+2
2021-10-07Proxy: disabled keepalive on extra data in non-buffered mode.Awdhesh Mathpal1-0/+1
The u->keepalive flag is initialized early if the response has no body (or an empty body), and needs to be reset if there are any extra data, similarly to how it is done in ngx_http_proxy_copy_filter(). Missed in 83c4622053b0.
2021-10-06Fixed $content_length cacheability with chunked (ticket #2252).Maxim Dounin1-0/+4
2021-09-10Request body: do not create temp file if there's nothing to write.Roman Arutyunyan1-1/+1
Do this only when the entire request body is empty and r->request_body_in_file_only is set. The issue manifested itself with missing warning "a client request body is buffered to a temporary file" when the entire rb->buf is full and all buffers are delayed by a filter.
2021-09-06HTTP/2: optimized processing of small DATA frames.Maxim Dounin1-54/+12
The request body filter chain is no longer called after processing a DATA frame. Instead, we now post a read event to do this. This ensures that multiple small DATA frames read during the same event loop iteration are coalesced together, resulting in much faster processing. Since rb->buf can now contain unprocessed data, window update is no longer sent in ngx_http_v2_state_read_data() in case of flow control being used due to filter buffering. Instead, window will be updated by ngx_http_v2_read_client_request_body_handler() in the posted read event.
2021-09-06HTTP/2: fixed timers left after request body reading.Maxim Dounin1-12/+12
Following rb->filter_need_buffering changes, request body reading is only finished after the filter chain is called and rb->last_saved is set. As such, with r->request_body_no_buffering, timer on fc->read is no longer removed when the last part of the body is received, potentially resulting in incorrect behaviour. The fix is to call ngx_http_v2_process_request_body() from the ngx_http_v2_read_unbuffered_request_body() function instead of directly calling ngx_http_v2_filter_request_body(), so the timer is properly removed.
2021-09-06HTTP/2: fixed window updates when buffering in filters.Maxim Dounin1-2/+18
In the body read handler, the window was incorrectly calculated based on the full buffer size instead of the amount of free space in the buffer. If the request body is buffered by a filter, and the buffer is not empty after the read event is generated by the filter to resume request body processing, this could result in "http2 negative window update" alerts. Further, in the body ready handler and in ngx_http_v2_state_read_data() the buffer wasn't cleared when the data were already written to disk, so the client might stuck without window updates.
2021-09-02Fixed debug logging.Roman Arutyunyan1-2/+2
2021-08-31HTTP/2: avoid memcpy() with NULL source and zero length.Maxim Dounin1-1/+3
Prodded by Clang Static Analyzer.
2021-08-29Request body: reading body buffering in filters.Maxim Dounin3-26/+182
If a filter wants to buffer the request body during reading (for example, to check an external scanner), it can now do so. To make it possible, the code now checks rb->last_saved (introduced in the previous change) along with rb->rest == 0. Since in HTTP/2 this requires flow control to avoid overflowing the request body buffer, so filters which need buffering have to set the rb->filter_need_buffering flag on the first filter call. (Note that each filter is expected to call the next filter, so all filters will be able set the flag if needed.)
2021-08-29Request body: introduced rb->last_saved flag.Maxim Dounin2-15/+54
It indicates that the last buffer was received by the save filter, and can be used to check this at higher levels. To be used in the following changes.
2021-08-29Request body: added alert to catch duplicate body saving.Maxim Dounin1-0/+6
If due to an error ngx_http_request_body_save_filter() is called more than once with rb->rest == 0, this used to result in a segmentation fault. Added an alert to catch such errors, just in case.
2021-08-29Request body: missing comments about initialization.Maxim Dounin1-0/+2
2021-08-29HTTP/2: improved handling of preread unbuffered requests.Maxim Dounin1-1/+1
Previously, fully preread unbuffered requests larger than client body buffer size were saved to disk, despite the fact that "unbuffered" is expected to imply no disk buffering.
2021-08-29HTTP/2: improved handling of END_STREAM in a separate DATA frame.Maxim Dounin1-0/+3
The save body filter saves the request body to disk once the buffer is full. Yet in HTTP/2 this might happen even if there is no need to save anything to disk, notably when content length is known and the END_STREAM flag is sent in a separate empty DATA frame. Workaround is to provide additional byte in the buffer, so saving the request body won't be triggered. This fixes unexpected request body disk buffering in HTTP/2 observed after the previous change when content length is known and the END_STREAM flag is sent in a separate empty DATA frame.
2021-08-29HTTP/2: reworked body reading to better match HTTP/1.x code.Maxim Dounin1-62/+96
In particular, now the code always uses a buffer limited by client_body_buffer_size. At the cost of an additional copy it ensures that small DATA frames are not directly mapped to small write() syscalls, but rather buffered in memory before writing. Further, requests without Content-Length are no longer forced to use temporary files.
2021-08-29HTTP/2: improved body reading logging.Maxim Dounin1-0/+6
2021-08-20Upstream: fixed timeouts with gRPC, SSL and select (ticket #2229).Maxim Dounin1-0/+4
With SSL it is possible that an established connection is ready for reading after the handshake. Further, events might be already disabled in case of level-triggered event methods. If this happens and ngx_http_upstream_send_request() blocks waiting for some data from the upstream, such as flow control in case of gRPC, the connection will time out due to no read events on the upstream connection. Fix is to explicitly check the c->read->ready flag if sending request blocks and post a read event if it is set. Note that while it is possible to modify ngx_ssl_handshake() to keep read events active, this won't completely resolve the issue, since there can be data already received during the SSL handshake (see 573bd30e46b4).
2021-08-16SSL: ciphers now set before loading certificates (ticket #2035).Maxim Dounin4-25/+25
To load old/weak server or client certificates it might be needed to adjust the security level, as introduced in OpenSSL 1.1.0. This change ensures that ciphers are set before loading the certificates, so security level changes via the cipher string apply to certificate loading.
2021-08-09Disabled HTTP/1.0 requests with Transfer-Encoding.Sergey Kandaurov1-0/+8
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.
2021-06-28Disabled control characters in the Host header.Maxim Dounin1-3/+4
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.
2021-06-28Improved logging of invalid headers.Maxim Dounin6-13/+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.
2021-06-28Disabled control characters and space in header names.Maxim Dounin3-4/+4
Control characters (0x00-0x1f, 0x7f), space, and colon were never allowed in header names. The only somewhat valid use is header continuation which nginx never supported and which is explicitly obsolete by RFC 7230. Previously, such headers were considered invalid and were ignored by default (as per ignore_invalid_headers directive). With this change, such headers are unconditionally rejected. It is expected to make nginx more resilient to various attacks, in particular, with ignore_invalid_headers switched off (which is inherently unsecure, though nevertheless sometimes used in the wild).
2021-06-28Disabled control characters in URIs.Maxim Dounin1-14/+28
Control characters (0x00-0x1f, 0x7f) were never allowed in URIs, and must be percent-encoded by clients. Further, these are not believed to appear in practice. On the other hand, passing such characters might make various attacks possible or easier, despite the fact that currently allowed control characters are not significant for HTTP request parsing.
2021-06-28Disabled spaces in URIs (ticket #196).Maxim Dounin4-70/+11
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.
2021-06-28Disabled requests with both Content-Length and Transfer-Encoding.Maxim Dounin1-2/+9
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.
2021-06-28Added CONNECT method rejection.Maxim Dounin4-17/+31
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.
2021-06-28Moved TRACE method rejection to a better place.Maxim Dounin1-7/+7
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.
2021-06-17gRPC: RST_STREAM(NO_ERROR) handling micro-optimization.Sergey Kandaurov1-0/+4
After 2096b21fcd10, a single RST_STREAM(NO_ERROR) may not result in an error. This change removes several unnecessary ctx->type checks for such a case.
2021-06-17gRPC: handling GOAWAY with a higher last stream identifier.Sergey Kandaurov1-0/+9
Previously, once received from upstream, it couldn't limit opening additional streams in a cached keepalive connection.
2021-06-01Fixed SSL logging with lingering close.Maxim Dounin1-0/+2
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).
2021-05-24Location header escaping in redirects (ticket #882).Ruslan Ermilov5-7/+80
The header is escaped in redirects based on request URI or location name (auto redirect).