8581 Commits

Author SHA1 Message Date
Vladimir Homutov 3b5da468b3 Stream: least_time balancer module
Example configuration:

upstream u {
    least_time connect | first_byte | last_byte [inflight];
    server a;
    server b;
}

Co-authored-by: Roman Arutyunyan <arut@nginx.com>
2026-05-04 21:19:40 +05:30
Vladimir Homutov 5760d6148e Upstream: least_time balancer module
The module implements load-balancing algorithm based on least average
response header/last_byte time and least number of active connections.

The optional "inflight" mode enables accounting of incomplete
requests/sessions.  This allows to mitigate cases when an upstream
server hangs and does not close connections.

Example configuration:

upstream u {
    least_time header | last_byte [inflight];
    server a;
    server b;
}

Co-authored-by: Roman Arutyunyan <arut@nginx.com>
2026-05-04 21:19:40 +05:30
Vladimir Homutov 45554176ca Upstream: locked version of ngx_*_upstream_free_round_robin_peer().
This allows optimizing ngx_http_upstream_free_least_time_peer() by
not releasing and re-taking the same lock.
2026-05-04 21:19:40 +05:30
Andrew Clayton 35510ddc94 Configure: fix gcc version detection in some corner cases
If the "gcc version ... " string appeared within "Configured with:", it
was picked up rather than the real gcc version string. This might then
break the configure scripts due to a malformed NGX_COMPILER macro.

The simple fix is to look for "gcc version ... " at the start of the
line, rather than anywhere within.

Suggested-by: Aleksei Bavshin <a.bavshin@nginx.com>
Closes: https://github.com/nginx/nginx/issues/1278
2026-05-01 22:43:35 +01:00
Sergey Kandaurov 6eb7dcdd98 Request body: restored buffered empty body special case
This restores a long-standing optimization when the entire request
body is empty and r->request_body_in_file_only is set, used to avoid
writing an empty file as initially introduced in 4c7f51136 (0.4.4).
The previous condition never worked with chunked body filter, where
rb->bufs holds at least the final chunk; in length body filter, it is
used to indicate the last received buffer since 2a7092138 (1.21.2).

The fix is to additionally check if it is the only empty buffer.

Found with UndefinedBehaviorSanitizer (pointer-overflow)
2026-04-30 15:09:24 +04:00
Sergey Kandaurov 484a9863e7 Stream: evaluate proxy_ssl_alpn once
To avoid disagreement with non-cacheable variables.
2026-04-30 15:07:34 +04:00
Henry Yuan 297b096464 Configure: renamed the upstream sticky module option.
The module can now be disabled with the
--without-http_upstream_sticky_module option to match
the naming convention used by other upstream modules.
Deprecated the --without-http_upstream_sticky option.

Closes: https://github.com/nginx/nginx/issues/1273
2026-04-29 09:58:29 -07:00
Andrew Clayton bac04c1b66 Update CONTRIBUTING.md
Adjust the subject and commit message body line length limits to 72
characters to match the commit message linter.
2026-04-24 17:33:41 +01:00
Andrew Clayton 07c7adfc7f GH: add a workflow to check for whitespace issues
This runs git-log(1) --check on *each* commit and will report any
issues, e.g.

  --- afe5753fa ("Changes made in upstream")
  src/http/ngx_http_upstream.c:415: trailing whitespace.
  +
  src/http/ngx_http_upstream.c:417: trailing whitespace.
  +      ngx_http_upstream_backend_ssl_protocol, 0,

Specific exceptions can be handled via gitattributes(5).
2026-04-24 17:33:41 +01:00
Andrew Clayton 1f27ab1c8f GH: check commit messages for the most common errors
This checks commit messages in a pull-request for the most common
problems we see.
2026-04-24 17:33:41 +01:00
Andrew Clayton 61c5178f04 GH: mark old issues & PRs as stale
Mark issues & pull-requests that have had no activity for a specified
amount of time as stale.
2026-04-24 17:33:41 +01:00
Andrew Clayton 6991e3e1c5 GH: post a new issue welcome comment
Whenever a new issue is created in GitHub, post a "welcome" message as a
comment.
2026-04-24 17:33:41 +01:00
Andrew Clayton 83ae7d30bf GH: update the GitHub pull-request template 2026-04-24 17:33:41 +01:00
Andrew Clayton b0a4d0fb82 Avoid undefined behaviour in ngx_pstrdup()
In the third call to ngx_pstrdup() for setting cycle->conf_param.data in
ngx_init_cycle() we would pass in a nulled ngx_str_t in the case there
was no -g command line option passed to nginx.

This would result in a

  memcpy(dst, NULL, 0)

which up to and including C23 is Undefined Behaviour.

Currently Clang and GCC (in this particular case) just treat this as a
no-op, so things just happen to work.

However some undefined behaviour sanitizers will throw an error when
this is hit, e.g. Clang and the zig compiler and it's probably best not
to rely on this behaviour.

It's worth noting that the next C standard will make this (and other
NULL related operations) defined behaviour.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf>
Closes: https://github.com/nginx/nginx/issues/1079
2026-04-20 19:56:40 +01:00
Vadim Zhestikov 98fc3bb78e Stream: support ALPN for proxy_ssl upstream.
Added the proxy_ssl_alpn directive, which sets the list of protocols
to advertise via ALPN during upstream TLS handshakes.  Each argument
is a complex value, so variables are accepted.  In particular,

    proxy_ssl_alpn $ssl_alpn_protocol;

inherits the protocol negotiated in the downstream TLS handshake.

When all evaluated values are empty or absent, no ALPN extension is
sent, equivalent to the directive not being set at all.

Closes #406 on GitHub.
2026-04-17 14:16:31 -07:00
Roman Arutyunyan d7dd7e9ae4 HTTP/3: optimize encoder stream memory usage
Previously, the encoder stream allocated each new inserted field in the
connection pool.  This memory was not freed until the end of the connection.
Now a special insert buffer is used for all inserts.
2026-04-16 19:47:46 +04:00
Roman Arutyunyan 4e89ce224f Restrict duplicate TE headers in HTTP/2 and HTTP/3
Following d3a76322cf, this change rejects requests which have multiple
TE headers.

Reported-by: geeknik <geeknik@protonmail.ch>
2026-04-16 19:47:03 +04:00
Sergey Kandaurov ff8221b4db SSL: logging level of "record layer failure" errors
The SSL_R_RECORD_LAYER_FAILURE ("record layer failure") errors are
reported by OpenSSL 3.2 or newer as the last record layer error for
various low level read errors.  Further, a976e6b9e (1.23.4) caused
to always log them at the "crit" level.  For example, the following
errors are observed on OpenSSL 3.2.0 - 4.0:

SSL_read() failed (SSL: error:0A000119:SSL routines::decryption failed
 or bad record mac error:0A000139:SSL routines::record layer failure)
SSL_read() failed (SSL: error:1C800066:Provider routines::cipher operation
 failed error:0A000119:SSL routines::decryption failed or bad record mac
 error:0A000139:SSL routines::record layer failure)
SSL_read() failed (SSL: error:0A00010B:SSL routines::wrong version number
 error:0A000139:SSL routines::record layer failure)

These errors are now logged at the "info" level.

Closes: https://github.com/nginx/nginx/issues/961
Co-authored-by: Smeet23 <smeetagrawal2003@gmail.com>
2026-04-16 18:39:23 +04:00
Sergey Kandaurov ea72fa1d92 QUIC: simplified ngx_quic_cbs_recv_rcd()
There's no need in for-loop, a single buffer is fed at a time.
2026-04-16 15:25:55 +04:00
Sergey Kandaurov 4dd7ec9ae4 QUIC: always populate ngx_quic_cbs_recv_rcd() output arguments
Although uninitialized values aren't used in practice due to the
nature of the OpenSSL code flow, this violates the API contract.

Reported by lukefr09 on GitHub.
2026-04-16 15:25:55 +04:00
Aleksei Bavshin abc72c5a57 SSL: compatibility with renamed error codes in OpenSSL 4.0.
SSL_R_SSL3_SESSION_ID_TOO_LONG is no longer available when building
OpenSSL 4.0 with no-deprecated.  Added the new name as a fallback.
2026-04-14 11:26:42 -06:00
Maxim Dounin aa09c19992 SSL: logging level of "invalid alert" errors.
The SSL_R_INVALID_ALERT ("invalid alert") errors are reported by OpenSSL
1.1.1 or newer if the client sends a malformed alert.  These errors are
now logged at the "info" level.

Signed-off-by: Aleksei Bavshin <a.bavshin@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/d89e0386b695>
2026-04-14 11:26:42 -06:00
Maxim Dounin 06c9d63fc8 SSL: logging level of all "SSL alert number N" errors.
Errors about alerts received from peers are generated by OpenSSL by adding
peer-provided alert description (from 0 to 255) to SSL_AD_REASON_OFFSET.
All such errors, including ones for unknown alerts, are now logged at the
"info" level, as these can be caused by a misbehaving client.

Signed-off-by: Aleksei Bavshin <a.bavshin@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/f5423ee155fe>
2026-04-14 11:26:42 -06:00
Sergey Kandaurov bbaac1d43f Updated OpenSSL used for win32 builds 2026-04-14 16:57:41 +04:00
Roman Arutyunyan d3a76322cf Restrict connection-specific headers in HTTP/2 and HTTP/3
As per RFC 9113 and RFC 9114, any message containing such headers MUST be
treated as malformed.

As per RFC 9110, Section 7.6.1, the following headers are considered
connection-specific:

- Connection
- Proxy-Connection
- Keep-Alive
- TE
- Transfer-Encoding
- Upgrade

The only exception is the TE header field, which MAY be present in a
request header, but it MUST NOT contain any value other than "trailers".
2026-04-14 09:53:13 +04:00
Roman Arutyunyan 00979ba9d8 Remove Proxy-Connection HTTP upstream header
As per RFC 9110, this header SHOULD be removed by a proxy.

Also, as per RFC 9113, this header MUST be removed when proxying to an
HTTP/2 backend.
2026-04-14 09:53:13 +04:00
Andrew Clayton b761b0485b GH: add a workflow to check for the 'version bump' commit
This checks pull-requests to make sure the 'Version bump' commit is
immediately after the last release commit/tag.

The check includes the commits in the pull-request, so if a pull-request
is adding this commit it will accept it and also if there are other
commits in the pull-request, as long as the 'Version bump' commit is
first.
2026-04-13 14:20:23 +01:00
Andrew Clayton 9772267278 Version bump 2026-04-13 14:20:23 +01:00
Sergey Kandaurov 5eaf45f11e nginx-1.29.8-RELEASE release-1.29.8 2026-04-07 15:37:12 +04:00
David Carlier 1709bffe6e Upstream: reset early_hints_length on upstream reinit.
When a request was retried to a new upstream after receiving 103
Early Hints from the previous one, the accumulated early_hints_length
was not reset, causing valid early hints from the next upstream to be
incorrectly rejected as "too big".
2026-04-06 20:59:00 +04:00
Zoey 067d766f21 Fix $request_port and $is_request_port in subrequests
Closes #1247.
2026-04-06 14:53:54 +04:00
Maxim Dounin 365694160a Added max_headers directive.
The directive limits the number of request headers accepted from clients.
While the total amount of headers is believed to be sufficiently limited
by the existing buffer size limits (client_header_buffer_size and
large_client_header_buffers), the additional limit on the number of headers
might be beneficial to better protect backend servers.

Requested by Maksim Yevmenkin.

Signed-off-by: Elijah Zupancic <e.zupancic@f5.com>
Origin: <https://freenginx.org/hg/nginx/rev/199dc0d6b05be814b5c811876c20af58cd361fea>
2026-04-06 14:08:36 +04:00
David Korczynski 06c30ec29d Upstream: fix integer underflow in charset parsing
The issue described below was only reproducible prior to
https://github.com/nginx/nginx/commit/7924a4ec6cb35291ea60a5f2a70ac0a034d94ff7

When parsing the `charset` parameter in the `Content-Type` header within
`ngx_http_upstream_copy_content_type`, an input such as `charset="`
resulted in an integer underflow.

In this scenario, both `p` and `last` point to the position immediately
following the opening quote. The logic to strip a trailing quote checked
`*(last - 1)` without verifying that `last > p`. This caused `last` to
be decremented to point to the opening quote itself, making `last < p`.

The subsequent length calculation `r->headers_out.charset.len = last - p`
resulted in -1, which wrapped to `SIZE_MAX` as `len` is a `size_t`. This
invalid length was later passed to `ngx_cpymem` in `ngx_http_header_filter`,
leading to an out-of-bounds memory access (detected as
`negative-size-param` by AddressSanitizer).

The fix ensures `last > p` before attempting to strip a trailing quote,
correctly resulting in a zero-length charset for malformed input.

The oss-fuzz payload that triggers this issue holds multiple 103 status
lines, and it's a sequence of 2 of those Content-Type headers that
trigger the ASAN report.

Co-authored-by: CodeMender <codemender-patching@google.com>
Fixes: https://issues.oss-fuzz.com/issues/486561029

Signed-off-by: David Korczynski <david@adalogics.com>
2026-04-06 14:07:18 +04:00
Eugene Grebenschikov 2ff1a969f3 Removed CLOCK_MONOTONIC_FAST support.
CLOCK_MONOTONIC_FAST, like CLOCK_MONOTONIC_COARSE, has low accuracy. It
shows noticeable timing variation for short intervals, which is visible
in metrics like $upstream_response_time for fast upstream responses.
This change complements the work started in commit f29d7ade5.
In addition to the reasons described in f29d7ade5, the performance of
CLOCK_MONOTONIC is good enough on modern hardware when using a TSC
timecounter. This is especially true when it is accessed through a
shared page, as implemented in FreeBSD 10.0 (see git commits
869fd80fd449 and aea810386d8e for details).

Co-authored-by: Sergey Kandaurov <pluknet@nginx.com>
2026-04-03 11:57:21 -07:00
Sergey Kandaurov 7924a4ec6c Upstream: fixed processing multiple 103 (early hints) responses.
The second 103 response in a row was treated as the final response header.
2026-04-02 20:54:32 +04:00
xuruidong 9fd94af4dd Update CONTRIBUTING.md 2026-03-31 15:36:50 +01:00
Sergey Kandaurov 0d025b4a94 SSL: compatibility with OpenSSL 4.0.
X509_get_issuer_name() and X509_get_subject_name() were changed to return
a const value.  Since it is passed to functions with a non const argument
in older versions, the const modifier is conditionally compiled as needed.

ASN1_INTEGER was made opaque.  ASN1_STRING accessors are used to preserve
the behaviour.  ASN1_STRING_get0_data() compat shim is provided for OpenSSL
< 1.1.0 where it does not exist.
2026-03-31 12:32:19 +04:00
Sergey Kandaurov 390767e6ec Version bump. 2026-03-31 12:32:19 +04:00
Eugene Grebenschikov 0de6e878ba Fixed the "include" directive inside the "geo" block.
The "include" directive should be able to include multiple files if
given a filename mask.

Completes remaining changes introduced in da4ffd8.

Closes: https://github.com/nginx/nginx/issues/1165
2026-03-24 11:20:16 -07:00
Roman Arutyunyan 5ac6f49371 nginx-1.29.7-RELEASE release-1.29.7 2026-03-24 19:38:34 +04:00
Sergey Kandaurov 18711f7754 Stream: fixed client certificate validation with OCSP.
Check for OCSP status was missed in 581cf2267, resulting
in a broken validation.

Reported by Mufeed VH of Winfunc Research.
2026-03-24 19:28:20 +04:00
Sergey Kandaurov 9bc13718fe Mail: fixed clearing s->passwd in auth http requests.
Previously, it was not properly cleared retaining length as part of
authenticating with CRAM-MD5 and APOP methods that expect to receive
password in auth response.  This resulted in null pointer dereference
and worker process crash in subsequent auth attempts with CRAM-MD5.

Reported by Arkadi Vainbrand.
2026-03-24 18:46:36 +04:00
Roman Arutyunyan 6f3145006b Mail: host validation.
Now host name resolved from client address is validated to only contain
the characters specified in RFC 1034, Section 3.5.  The validation allows
to avoid injections when using the resolved host name in auth_http and
smtp proxy.

Reported by Asim Viladi Oglu Manizada, Colin Warren,
Xiao Liu (Yunnan University), Yuan Tan (UC Riverside), and
Bird Liu (Lanzhou University).
2026-03-24 18:46:08 +04:00
Roman Arutyunyan 9739e755b8 Dav: destination length validation for COPY and MOVE.
Previously, when alias was used in a location with Dav COPY or MOVE
enabled, and the destination URI was shorter than the alias, integer
underflow could happen in ngx_http_map_uri_to_path(), which could
result in heap buffer overwrite, followed by a possible segfault.
With some implementations of memcpy(), the segfault could be avoided
and the overwrite could result in a change of the source or destination
file names to be outside of the location root.

Reported by Calif.io in collaboration with Claude and Anthropic Research.
2026-03-24 18:45:25 +04:00
Roman Arutyunyan 3568812cf9 Mp4: fixed possible integer overflow on 32-bit platforms.
Previously, a 32-bit overflow could happen while validating atom entries
count.  This allowed processing of an invalid atom with entrires beyond
its boundaries with reads and writes outside of the allocated mp4 buffer.

Reported by Prabhav Srinath (sprabhav7).
2026-03-24 18:44:57 +04:00
Roman Arutyunyan 7725c372c2 Mp4: avoid zero size buffers in output.
Previously, data validation checks did not cover the cases when the output
contained empty buffers.  Such buffers are considered illegal and produce
"zero size buf in output" alerts.  The change rejects the mp4 files which
produce such alerts.

Also, the change fixes possible buffer overread and overwrite that could
happen while processing empty stco and co64 atoms, as reported by
Pavel Kohout (Aisle Research) and Tim Becker.
2026-03-24 18:12:29 +04:00
Roman Arutyunyan d787755d50 Upstream keepalive: fixed parameter parsing. 2026-03-24 15:38:16 +04:00
Roman Semenov 6bb27a6312 Proxy: enabled HTTP/1.1 by default for upstream connections.
Updates the proxy module to use HTTP/1.1 as the default protocol when
communicating with upstream servers. This change unlocks features
such as persistent connections and chunked transfer encoding. Configurations
that require HTTP/1.0 can still override the protocol explicitly.
2026-03-24 14:28:52 +04:00
Roman Semenov 4fbe4b6274 Upstream: enabled keepalive by default for explicit upstreams.
Keepalive is now automatically enabled in the "local" mode for upstreams
defined in configuration files. Cached keepalive connections are no longer
shared between different locations referencing the same explicit upstream
unless keepalive is explicitly configured without the "local" parameter.

To disable keepalive entirely, use keepalive 0; inside the upstream block.
To allow sharing cached connections between locations, configure
keepalive <max_cached>; without the "local" parameter.
2026-03-24 14:28:52 +04:00
Roman Semenov c5d36eac33 Upstream keepalive: distinguish cached connections by location.
The new "local" parameter prevents sharing cached keepalive connections
between location blocks. Connections are now reused only within the same
location.
2026-03-24 14:28:52 +04:00