]> git.kaiwu.me - nginx.git/log
nginx.git
23 hours agoReject HTTP CONNECT method with no port after colon master
Sergey Kandaurov [Fri, 8 May 2026 15:38:43 +0000 (19:38 +0400)]
Reject HTTP CONNECT method with no port after colon

4 days agoSupport 407 code in "satisfy any" and "auth_delay"
Roman Arutyunyan [Thu, 7 May 2026 10:08:25 +0000 (14:08 +0400)]
Support 407 code in "satisfy any" and "auth_delay"

Notably, "auth_delay" now delays the response for both 401 and 407.
Also, in the "satisfy any" mode, the next access/auth attempt is made
for 401, 403 and 407.

4 days agoProxy authentication for CONNECT requests
Roman Arutyunyan [Thu, 16 Apr 2026 16:57:24 +0000 (20:57 +0400)]
Proxy authentication for CONNECT requests

Notably, ngx_http_auth_basic_module uses Proxy-Authorization input
header, Proxy-Authenticate output header and HTTP code 407 instead
of Authorization, WWW-Authenticate and 401 respectively.

4 days agoHTTP tunnel module
Roman Arutyunyan [Thu, 16 Apr 2026 16:48:02 +0000 (20:48 +0400)]
HTTP tunnel module

The module handles CONNECT requests and establishes a tunnel to a
backend.

Example config:

http {

    map $request_port $allow_port {
        80             1;
        443            1;
    }

    map $host $allow_host {
        hostnames;

        example.com    1;
        *.example.org  1;
    }

    server {
        listen 8000;

        resolver dns.example.com;

        if ($allow_port != 1) {
            return 403;
        }

        if ($allow_host != 1) {
            return 403;
        }

        tunnel_pass;
    }
}

Request:

    $ curl -x 127.0.0.1:8000 https://example.com

5 days agoGH: update the stale PR/issue workflow
Andrew Clayton [Tue, 5 May 2026 18:17:59 +0000 (19:17 +0100)]
GH: update the stale PR/issue workflow

To avoid future churn give the workflow a generic name, don't operate on
pull-requests, and extend the issues stale date to 365 days and update
its message.

5 days agoProxy: fix keepalive for HTTP/2 with explicit or no body
Roman Arutyunyan [Tue, 5 May 2026 11:22:05 +0000 (15:22 +0400)]
Proxy: fix keepalive for HTTP/2 with explicit or no body

Previously, when an HTTP/2 request had no body or an explicit body
was set by proxy_set_body, the request consisted of only one buffer,
which had no b->last_buf flag set.  This prevented ctx->output_closed
from being set after processing this buffer.  Consequently,
u->keepalive might not be set to store the connection in the
keepalive cache.

6 days agoDav: improved path validation for COPY and MOVE operations
Sai Krishna Kumar Reddy Yadamakanti [Tue, 5 May 2026 12:01:04 +0000 (12:01 +0000)]
Dav: improved path validation for COPY and MOVE operations

The COPY and MOVE handler did not validate whether source and
destination paths referred to the same resource or a parent-child
collection relationship, which could corrupt or destroy files.

Now 403 is returned if paths match or one is a prefix of the other.

Reported by Mufeed VH of Winfunc Research.

7 days agoStream: least_time balancer module
Vladimir Homutov [Fri, 28 Oct 2016 13:01:53 +0000 (16:01 +0300)]
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>
7 days agoUpstream: least_time balancer module
Vladimir Homutov [Fri, 28 Oct 2016 13:01:53 +0000 (16:01 +0300)]
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>
7 days agoUpstream: locked version of ngx_*_upstream_free_round_robin_peer().
Vladimir Homutov [Mon, 24 Oct 2016 09:41:10 +0000 (12:41 +0300)]
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.

10 days agoConfigure: fix gcc version detection in some corner cases
Andrew Clayton [Wed, 29 Apr 2026 18:18:03 +0000 (19:18 +0100)]
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
12 days agoRequest body: restored buffered empty body special case
Sergey Kandaurov [Fri, 14 Nov 2025 12:06:56 +0000 (16:06 +0400)]
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)

12 days agoStream: evaluate proxy_ssl_alpn once
Sergey Kandaurov [Tue, 28 Apr 2026 09:31:03 +0000 (13:31 +0400)]
Stream: evaluate proxy_ssl_alpn once

To avoid disagreement with non-cacheable variables.

12 days agoConfigure: renamed the upstream sticky module option.
Henry Yuan [Thu, 23 Apr 2026 21:24:24 +0000 (21:24 +0000)]
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
2 weeks agoUpdate CONTRIBUTING.md
Andrew Clayton [Fri, 20 Mar 2026 04:46:01 +0000 (04:46 +0000)]
Update CONTRIBUTING.md

Adjust the subject and commit message body line length limits to 72
characters to match the commit message linter.

2 weeks agoGH: add a workflow to check for whitespace issues
Andrew Clayton [Thu, 26 Mar 2026 17:51:56 +0000 (17:51 +0000)]
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).

2 weeks agoGH: check commit messages for the most common errors
Andrew Clayton [Wed, 4 Mar 2026 18:52:07 +0000 (18:52 +0000)]
GH: check commit messages for the most common errors

This checks commit messages in a pull-request for the most common
problems we see.

2 weeks agoGH: mark old issues & PRs as stale
Andrew Clayton [Wed, 4 Mar 2026 18:44:33 +0000 (18:44 +0000)]
GH: mark old issues & PRs as stale

Mark issues & pull-requests that have had no activity for a specified
amount of time as stale.

2 weeks agoGH: post a new issue welcome comment
Andrew Clayton [Wed, 4 Mar 2026 18:42:07 +0000 (18:42 +0000)]
GH: post a new issue welcome comment

Whenever a new issue is created in GitHub, post a "welcome" message as a
comment.

2 weeks agoGH: update the GitHub pull-request template
Andrew Clayton [Thu, 5 Mar 2026 01:34:29 +0000 (01:34 +0000)]
GH: update the GitHub pull-request template

3 weeks agoAvoid undefined behaviour in ngx_pstrdup()
Andrew Clayton [Thu, 19 Mar 2026 04:21:21 +0000 (04:21 +0000)]
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
3 weeks agoStream: support ALPN for proxy_ssl upstream.
Vadim Zhestikov [Mon, 2 Feb 2026 22:46:00 +0000 (14:46 -0800)]
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.

3 weeks agoHTTP/3: optimize encoder stream memory usage
Roman Arutyunyan [Fri, 10 Apr 2026 17:42:18 +0000 (21:42 +0400)]
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.

3 weeks agoRestrict duplicate TE headers in HTTP/2 and HTTP/3
Roman Arutyunyan [Wed, 15 Apr 2026 09:49:00 +0000 (13:49 +0400)]
Restrict duplicate TE headers in HTTP/2 and HTTP/3

Following d3a76322cf7a, this change rejects requests which have multiple
TE headers.

Reported-by: geeknik <geeknik@protonmail.ch>
3 weeks agoSSL: logging level of "record layer failure" errors
Sergey Kandaurov [Thu, 16 Apr 2026 13:57:13 +0000 (17:57 +0400)]
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>
3 weeks agoQUIC: simplified ngx_quic_cbs_recv_rcd()
Sergey Kandaurov [Wed, 15 Apr 2026 18:22:43 +0000 (22:22 +0400)]
QUIC: simplified ngx_quic_cbs_recv_rcd()

There's no need in for-loop, a single buffer is fed at a time.

3 weeks agoQUIC: always populate ngx_quic_cbs_recv_rcd() output arguments
Sergey Kandaurov [Wed, 15 Apr 2026 18:12:28 +0000 (22:12 +0400)]
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.

3 weeks agoSSL: compatibility with renamed error codes in OpenSSL 4.0.
Aleksei Bavshin [Tue, 7 Apr 2026 16:26:40 +0000 (09:26 -0700)]
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.

3 weeks agoSSL: logging level of "invalid alert" errors.
Maxim Dounin [Sun, 5 May 2024 21:07:18 +0000 (00:07 +0300)]
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>

3 weeks agoSSL: logging level of all "SSL alert number N" errors.
Maxim Dounin [Sun, 5 May 2024 21:06:15 +0000 (00:06 +0300)]
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>

4 weeks agoUpdated OpenSSL used for win32 builds
Sergey Kandaurov [Tue, 14 Apr 2026 12:48:30 +0000 (16:48 +0400)]
Updated OpenSSL used for win32 builds

4 weeks agoRestrict connection-specific headers in HTTP/2 and HTTP/3
Roman Arutyunyan [Wed, 8 Apr 2026 13:19:24 +0000 (17:19 +0400)]
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".

4 weeks agoRemove Proxy-Connection HTTP upstream header
Roman Arutyunyan [Wed, 8 Apr 2026 12:51:07 +0000 (16:51 +0400)]
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.

4 weeks agoGH: add a workflow to check for the 'version bump' commit
Andrew Clayton [Wed, 1 Apr 2026 18:17:55 +0000 (19:17 +0100)]
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.

4 weeks agoVersion bump
Andrew Clayton [Mon, 13 Apr 2026 13:18:45 +0000 (14:18 +0100)]
Version bump

5 weeks agonginx-1.29.8-RELEASE release-1.29.8
Sergey Kandaurov [Mon, 6 Apr 2026 17:40:05 +0000 (21:40 +0400)]
nginx-1.29.8-RELEASE

5 weeks agoUpstream: reset early_hints_length on upstream reinit.
David Carlier [Sun, 15 Mar 2026 15:56:01 +0000 (15:56 +0000)]
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".

5 weeks agoFix $request_port and $is_request_port in subrequests
Zoey [Sun, 5 Apr 2026 09:31:15 +0000 (11:31 +0200)]
Fix $request_port and $is_request_port in subrequests

Closes #1247.

5 weeks agoAdded max_headers directive.
Maxim Dounin [Thu, 23 May 2024 21:20:01 +0000 (00:20 +0300)]
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>

5 weeks agoUpstream: fix integer underflow in charset parsing
David Korczynski [Wed, 4 Mar 2026 09:27:45 +0000 (01:27 -0800)]
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>
5 weeks agoRemoved CLOCK_MONOTONIC_FAST support.
Eugene Grebenschikov [Wed, 1 Apr 2026 18:03:21 +0000 (11:03 -0700)]
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>
5 weeks agoUpstream: fixed processing multiple 103 (early hints) responses.
Sergey Kandaurov [Thu, 2 Apr 2026 13:41:56 +0000 (17:41 +0400)]
Upstream: fixed processing multiple 103 (early hints) responses.

The second 103 response in a row was treated as the final response header.

6 weeks agoUpdate CONTRIBUTING.md
xuruidong [Thu, 19 Mar 2026 13:02:05 +0000 (21:02 +0800)]
Update CONTRIBUTING.md

6 weeks agoSSL: compatibility with OpenSSL 4.0.
Sergey Kandaurov [Tue, 10 Mar 2026 12:28:04 +0000 (16:28 +0400)]
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.

6 weeks agoVersion bump.
Sergey Kandaurov [Mon, 30 Mar 2026 15:26:17 +0000 (19:26 +0400)]
Version bump.

6 weeks agoFixed the "include" directive inside the "geo" block.
Eugene Grebenschikov [Thu, 12 Mar 2026 00:57:05 +0000 (17:57 -0700)]
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
6 weeks agonginx-1.29.7-RELEASE release-1.29.7
Roman Arutyunyan [Thu, 19 Mar 2026 14:53:00 +0000 (18:53 +0400)]
nginx-1.29.7-RELEASE

6 weeks agoStream: fixed client certificate validation with OCSP.
Sergey Kandaurov [Tue, 17 Mar 2026 15:20:03 +0000 (19:20 +0400)]
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.

7 weeks agoMail: fixed clearing s->passwd in auth http requests.
Sergey Kandaurov [Wed, 18 Mar 2026 12:39:37 +0000 (16:39 +0400)]
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.

7 weeks agoMail: host validation.
Roman Arutyunyan [Thu, 26 Feb 2026 07:52:53 +0000 (11:52 +0400)]
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).

7 weeks agoDav: destination length validation for COPY and MOVE.
Roman Arutyunyan [Mon, 16 Mar 2026 16:13:03 +0000 (20:13 +0400)]
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.

7 weeks agoMp4: fixed possible integer overflow on 32-bit platforms.
Roman Arutyunyan [Mon, 2 Mar 2026 17:12:34 +0000 (21:12 +0400)]
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).

7 weeks agoMp4: avoid zero size buffers in output.
Roman Arutyunyan [Sat, 21 Feb 2026 08:04:36 +0000 (12:04 +0400)]
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.

7 weeks agoUpstream keepalive: fixed parameter parsing.
Roman Arutyunyan [Tue, 24 Mar 2026 11:12:05 +0000 (15:12 +0400)]
Upstream keepalive: fixed parameter parsing.

7 weeks agoProxy: enabled HTTP/1.1 by default for upstream connections.
Roman Semenov [Tue, 27 Jan 2026 20:37:11 +0000 (12:37 -0800)]
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.

7 weeks agoUpstream: enabled keepalive by default for explicit upstreams.
Roman Semenov [Mon, 23 Mar 2026 18:03:26 +0000 (11:03 -0700)]
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.

7 weeks agoUpstream keepalive: distinguish cached connections by location.
Roman Semenov [Thu, 19 Mar 2026 19:47:14 +0000 (12:47 -0700)]
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.

7 weeks agoAdded COMPAT section to ngx_log_t.
Dmitry Plotnikov [Thu, 19 Mar 2026 21:20:50 +0000 (21:20 +0000)]
Added COMPAT section to ngx_log_t.

7 weeks agoThe "multipath" parameter of the "listen" directive.
Sergey Kandaurov [Thu, 16 Oct 2025 15:22:56 +0000 (15:22 +0000)]
The "multipath" parameter of the "listen" directive.

When configured, it enables Multipath TCP support on a listen socket.
As of now it works on Linux starting with Linux 5.6 and glibc 2.32,
where it is enabled with an IPPROTO_MPTCP socket(2) protocol.

To avoid EADDRINUSE errors in bind() and listen() when transitioning
between sockets with different protocols, SO_REUSEPORT is set on both
sockets.  See f7f1607bf for potential implications.

Based on previous work by Maxime Dourov and Anthony Doeraene.

8 weeks agogRPC: reset buffer chains on upstream reinit.
David Carlier [Fri, 20 Feb 2026 05:08:09 +0000 (05:08 +0000)]
gRPC: reset buffer chains on upstream reinit.

Previously, ctx->out was not cleared in ngx_http_grpc_reinit_request(),
which could cause queued HTTP/2 control frames (SETTINGS ACK, PING ACK,
WINDOW_UPDATE) to be sent on next upstream.

Additionally, ctx->in and ctx->busy needs to be cleared to avoid similar
problems with buffered request body fixed in cd12dc4f1.

8 weeks agoProxy: reset pending control frames on HTTP/2 upstream reinit.
David Carlier [Thu, 19 Feb 2026 07:26:42 +0000 (07:26 +0000)]
Proxy: reset pending control frames on HTTP/2 upstream reinit.

Previously, ctx->out was not cleared in ngx_http_proxy_v2_reinit_request(),
which could cause stale HTTP/2 control frames (SETTINGS ACK, PING ACK,
WINDOW_UPDATE) queued for the old upstream connection to be sent to a new
upstream connection during a retry.

2 months agoProxy authentication definitions.
Roman Arutyunyan [Tue, 10 Mar 2026 12:43:41 +0000 (16:43 +0400)]
Proxy authentication definitions.

2 months agoVersion bump.
Roman Arutyunyan [Wed, 11 Mar 2026 15:28:31 +0000 (19:28 +0400)]
Version bump.

2 months agonginx-1.29.6-RELEASE release-1.29.6
Sergey Kandaurov [Tue, 10 Mar 2026 01:44:53 +0000 (05:44 +0400)]
nginx-1.29.6-RELEASE

2 months agoFixed typos.
Sergey Kandaurov [Tue, 10 Mar 2026 01:48:10 +0000 (05:48 +0400)]
Fixed typos.

2 months agoUpdated zlib used for win32 builds.
Sergey Kandaurov [Tue, 10 Mar 2026 13:06:35 +0000 (17:06 +0400)]
Updated zlib used for win32 builds.

2 months agoSticky: fixed expiration of learned sessions after reload.
Aleksei Bavshin [Tue, 17 Feb 2026 20:02:59 +0000 (12:02 -0800)]
Sticky: fixed expiration of learned sessions after reload.

Previously, the expiration timer for learned session was not started
until a new session is created.  This could lead to the sessions being
active past the expiration time.

2 months agoSticky: samesite=<strict|lax|none> cookie flags.
Vladimir Kokshenev [Sun, 1 Nov 2020 23:03:08 +0000 (15:03 -0800)]
Sticky: samesite=<strict|lax|none> cookie flags.

Adds new options for the "sticky cookie" directive to set
samesite=<strict|lax|none> cookie flags.

2 months agoSticky: added the "header" parameter in the learn mode.
Vladimir Homutov [Thu, 8 Jun 2017 12:39:06 +0000 (15:39 +0300)]
Sticky: added the "header" parameter in the learn mode.

With this parameter set, sessions are learned after receiving upstream headers.

2 months agoSticky: added the "max-age" attribute to cookie.
Vladimir Homutov [Fri, 7 Apr 2017 13:28:15 +0000 (16:28 +0300)]
Sticky: added the "max-age" attribute to cookie.

RFC 6265 defines "Max-Age" cookie attribute in section 5.2.2.

If the "expires" option is passed to the "sticky" directive, "max-age"
attribute will appear in cookies set by the module with corresponding
value in seconds.

For the special "max" value of the "expires" option, corresponding "max-age"
attribute value will be set to 315360000 seconds (10 years, similar to
how its done in headers_filter module for the "Cache-Control" header).

2 months agoSticky: added variables support to cookie domain.
Vladimir Homutov [Wed, 28 Sep 2016 07:55:58 +0000 (10:55 +0300)]
Sticky: added variables support to cookie domain.

2 months agoSticky: added "httponly" and "secure" attributes.
Vladimir Homutov [Tue, 17 Mar 2015 15:46:15 +0000 (18:46 +0300)]
Sticky: added "httponly" and "secure" attributes.

The attributes are described in RFC6265, sections 4.1.2.5 and 4.1.2.6
respectively.

2 months agoSticky: added "draining" peer state.
Vladimir Homutov [Thu, 28 Aug 2014 07:53:49 +0000 (11:53 +0400)]
Sticky: added "draining" peer state.

While peer is draining, only sticky requests are served and the peer is never
selected to process new requests.

Co-authored-by: Ruslan Ermilov <ru@nginx.com>
2 months agoUpstream: introduced a new macro for down value.
Aleksei Bavshin [Wed, 4 Mar 2026 19:35:41 +0000 (11:35 -0800)]
Upstream: introduced a new macro for down value.

2 months agoSticky: added the "learn" mode.
Vladimir Homutov [Mon, 5 May 2014 07:53:10 +0000 (11:53 +0400)]
Sticky: added the "learn" mode.

In this mode, nginx "learns" which client uses which proxied server by
analyzing headers of client requests and proxied server responses.

For example, a proxied server may start sessions by issuing the "Set-Cookie"
header field to set cookie 'sid' and returning clients will bring the cookie
with the same name.

The following configuration may be used to handle this case:

upstream u1 {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;

    sticky learn timeout=10m zone=sess:1m
           create=$upstream_cookie_sid
           lookup=$cookie_sid;
}

Co-authored-by: Ruslan Ermilov <ru@nginx.com>
Co-authored-by: Maxim Dounin <mdounin@mdounin.ru>
2 months agoUpstream: added sticky sessions support for upstreams.
Vladimir Homutov [Tue, 2 Apr 2013 21:44:36 +0000 (01:44 +0400)]
Upstream: added sticky sessions support for upstreams.

Sticky sessions allow to route the same client to the same upstream server.

- upstream structures are extended to keep session-related information

- existing balancing modules are updated to provide an id of the selected
  server (SID) in pc->sid, and to select the server, given it's SID.

- other balancing modules are allowed to set the pc->hint value to choose
  the desired peer.  The sticky module will not change the hint if it's
  already set.

- the feature is enabled by default and can be disabled with the
  "--without-http_upstream_sticky" switch of the configure script.

The following configuration can be used to enable sticky sessions for
supported balancing modules:

    upstream u1 {
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;

        sticky cookie server_id expires=1h domain=.example.com path=/;
    }

Co-authored-by: Ruslan Ermilov <ru@nginx.com>
Co-authored-by: Roman Arutyunyan <arut@nginx.com>
Co-authored-by: Maxim Dounin <mdounin@mdounin.ru>
2 months agoMail: fixed type overflow in IMAP literal length parser.
Sergey Kandaurov [Fri, 27 Feb 2026 17:46:04 +0000 (21:46 +0400)]
Mail: fixed type overflow in IMAP literal length parser.

The overflow is safe, because the maximum length of literals
is limited with the "imap_client_buffer" directive.

Reported by BartÅ‚omiej Dmitruk.

2 months agoMail: stricter IMAP literals validation.
Sergey Kandaurov [Fri, 27 Feb 2026 17:18:16 +0000 (21:18 +0400)]
Mail: stricter IMAP literals validation.

As clarified in RFC 3501, Section 7.5, literals are followed
either by SP, for additional command arguments, or CRLF.

2 months agoAdded an option to skip the F5 CLA workflow.
Alessandro Fael Garcia [Mon, 23 Feb 2026 23:40:37 +0000 (23:40 +0000)]
Added an option to skip the F5 CLA workflow.

There are some scenarios where the F5 CLA workflow should not run. This commit adds the ability to skip the F5 CLA by using the "skip-cla" label.

2 months agoQUIC: improved error handling in OpenSSL compat layer.
user.email [Tue, 24 Feb 2026 01:33:57 +0000 (19:33 -0600)]
QUIC: improved error handling in OpenSSL compat layer.

Previously ngx_quic_compat_create_record() could try to encrypt a TLS
record even if encryption context was missing, which resulted in a NULL
pointer dereference.

The context is created by ngx_quic_compat_set_encryption_secret() called
from the OpenSSL keylog callback.  If an error occurred in that function,
the context could remain missing.  This could happen under memory pressure,
if an allocation failed inside this function.

The fix is to handle errors from ngx_quic_compat_set_encryption_secret()
and set qc->error to trigger an error after SSL_do_handshake() return.
Also, a check for context is added to ngx_quic_compat_create_record()
to avoid other similar issues.

2 months agoQUIC: worker-bound stateless reset tokens.
Roman Arutyunyan [Thu, 26 Feb 2026 14:36:52 +0000 (18:36 +0400)]
QUIC: worker-bound stateless reset tokens.

Previously, it was possible to obtain a stateless reset token for a
connection by routing its packet to a wrong worker.  This allowed to
terminate the connection.

The fix is to bind stateless reset token to the worker number.

2 months agoUpdating welcome page with links and more details.
buulam [Fri, 20 Feb 2026 15:25:53 +0000 (07:25 -0800)]
Updating welcome page with links and more details.

2 months agoQUIC: fixed bpf compilation with newer Linux kernels.
Roman Arutyunyan [Tue, 24 Sep 2024 10:53:45 +0000 (14:53 +0400)]
QUIC: fixed bpf compilation with newer Linux kernels.

QUIC bpf program previously used struct bpf_map_def which was
deprecated in [1] (kernel version 5.18) and removed in [2] (kernel 6.1).
New-style BTF map definitions were added in [3] (linux kernel 5.3).

Switching the program to BTF is however not necessary since nginx has
its own relocation procedure which allows referencing the real map
structure by its file descriptor allocated earlier.  In particular,
bpf instruction BPF_LD_IMM64 (0x18/0x0) is substituted with instruction
BPF_LD_MAP_FD (0x18/0x1) and map_fd is stored in the imm field, see [4]
and [5] for details.

To fix compilation, struct bpf_map_def is changed to a known type (int)
and "extern" is added to indicate external linkage and reduce object
file size.

[1] https://github.com/torvalds/linux/commit/93b8952d223af03c51fba0c6258173d2ffbd2cb7
[2] https://github.com/torvalds/linux/commit/dc567045f1590f6460d3e9a6ea6ad5e600b58b84
[3] https://github.com/torvalds/linux/commit/abd29c9314595b1ee5ec6c61d7c49a497ffb30a3
[4] https://github.com/torvalds/linux/blob/master/include/linux/filter.h
[5] https://datatracker.ietf.org/doc/rfc9669/

2 months agoQUIC: Stateless Reset rate limiting.
Sergey Kandaurov [Wed, 25 Feb 2026 17:09:21 +0000 (21:09 +0400)]
QUIC: Stateless Reset rate limiting.

It uses a bloom filter to limit sending Stateless Reset packets no more
than once per second in average for the given address.  This allows to
address resource asymmetry from precomputed packets, as well as to limit
potential Stateless Reset exchange.

2 months agoQUIC: refactored ngx_quic_address_hash().
Sergey Kandaurov [Wed, 25 Feb 2026 17:07:01 +0000 (21:07 +0400)]
QUIC: refactored ngx_quic_address_hash().

Now it accepts an optional salt, to be used in a subsequent change.

2 months agoQUIC: moved ngx_quic_address_hash().
Sergey Kandaurov [Fri, 20 Feb 2026 15:01:20 +0000 (19:01 +0400)]
QUIC: moved ngx_quic_address_hash().

2 months agoQUIC: limited size of generated Stateless Reset packets.
Sergey Kandaurov [Fri, 20 Feb 2026 14:52:56 +0000 (18:52 +0400)]
QUIC: limited size of generated Stateless Reset packets.

Made sure to send packets smaller than the triggering packet,
following RFC 9000, Section 10.3.3.

Reported-by: cyberspace61
2 months agoQUIC: adjusted minimum packet size to send Stateless Reset.
Sergey Kandaurov [Fri, 20 Feb 2026 14:59:06 +0000 (18:59 +0400)]
QUIC: adjusted minimum packet size to send Stateless Reset.

Now to be valid, it also assumes the Connection ID we require from a client.

2 months agoResolver: fixed off-by-one read in ngx_resolver_copy().
Roman Arutyunyan [Mon, 23 Feb 2026 14:29:16 +0000 (18:29 +0400)]
Resolver: fixed off-by-one read in ngx_resolver_copy().

It is believed to be harmless, see a similar change 077a890a76ff.

Reported-by: geeknik <geeknik@protonmail.ch>
2 months agoMp4: validate sync sample values in stss atom.
CodeByMoriarty [Mon, 23 Feb 2026 00:45:47 +0000 (16:45 -0800)]
Mp4: validate sync sample values in stss atom.

Per ISO 14496-12 Section 8.6.2, sync sample numbers must be 1-based.
A zero-valued stss entry caused ngx_http_mp4_seek_key_frame() to
return a key_prefix exceeding the samples consumed in the forward
stts pass, which led the backward loop in ngx_http_mp4_crop_stts_data()
to walk past the beginning of the stts data buffer.

The fix validates each stss entry in ngx_http_mp4_seek_key_frame()
and returns an error if a zero sync sample is encountered.  The
function signature is changed to return ngx_int_t so it can signal
errors to the caller.

2 months agoSCGI: fixed passing CONTENT_LENGTH in unbuffered mode.
Sergey Kandaurov [Fri, 30 Jan 2026 13:06:38 +0000 (17:06 +0400)]
SCGI: fixed passing CONTENT_LENGTH in unbuffered mode.

Passing requests to SCGI uses a recalculated size of a request body
as per changes made in d60b8d10f (1.3.9) to support CONTENT_LENGTH
with chunked body requests.  This, however, is not compatible with
unbuffered mode introduced later in 7ec559df5 (1.7.11), where such
an approach may not always represent complete request body.

The fix is to use r->headers_in.content_length_n representing either
original Content-Length, if any, or a recalculated value from request
body filters, such as chunked body filter.

Reported by Mufeed VH.

2 months agoImproved $cookie_ evaluation.
Vadim Zhestikov [Fri, 19 Dec 2025 00:45:21 +0000 (16:45 -0800)]
Improved $cookie_ evaluation.

In case "Cookie" header is sent by client, multiple cookie pairs were
incorrectly split by a semicolon and comma.

Now they are split by a semicolon only.

For example, next variables will be found for "Cookie: a=b, c=d; e=f":
- $cookie_a: "b, c=d"
- $cookie_e: "f"

Closes #1042 on GitHub.

2 months agoProxy: fixed HTTP/2 upstream with caching enabled.
Roman Arutyunyan [Wed, 11 Feb 2026 12:29:37 +0000 (12:29 +0000)]
Proxy: fixed HTTP/2 upstream with caching enabled.

Previously, when proxy_cache and keepalive were both enabled with an
HTTP/2 upstream, the second request for a cached resource could fail with
"upstream sent frame for unknown stream" error followed by "cache file
contains invalid header".

This happened because ctx->id was set to 1 in the case when no upstream
connection exists (e.g. cache hit), making the stream id check fail when
the cached response contained frames from a different stream.

The fix is to set ctx->id to 0 when there is no upstream connection,
indicating that no real stream exists, and skip the stream id validation
in this case.  Also, ctx->id = 1 is now set only for new connections,
not in the shared done label.

Closes: https://github.com/nginx/nginx/issues/1101
2 months agoVersion bump.
Roman Arutyunyan [Wed, 11 Feb 2026 14:54:35 +0000 (18:54 +0400)]
Version bump.

3 months agonginx-1.29.5-RELEASE release-1.29.5
Roman Arutyunyan [Wed, 4 Feb 2026 13:43:03 +0000 (17:43 +0400)]
nginx-1.29.5-RELEASE

3 months agoUpstream: reinit upstream after reading bad response.
Roman Arutyunyan [Wed, 28 Jan 2026 16:38:38 +0000 (20:38 +0400)]
Upstream: reinit upstream after reading bad response.

Previously, when connecting to a backend, if the read event handler was
called before the write event handler, and the received response triggered
a next upstream condition, then ngx_http_upstream_reinit() was not called
to clean up the old upstream context.  This had multiple implications.

For all proxy modules, since the last upstream response was not cleaned up,
it was mixed with the next upstream response.  This could result in ignoring
the second response status code, duplicate response headers or reporting
old upstream header errors.

With ngx_http_grpc_module and ngx_http_proxy_v2_module, ctx->connection
was left dangling since the object it referenced was allocated from the
last upstream connection pool, which was deleted when freeing last upstream.
This lead to use-after-free when trying to reuse this object for the next
upstream.

3 months agoUpstream: detect premature plain text response from SSL backend.
Roman Arutyunyan [Thu, 29 Jan 2026 09:27:32 +0000 (13:27 +0400)]
Upstream: detect premature plain text response from SSL backend.

When connecting to a backend, the connection write event is triggered
first in most cases.  However if a response arrives quickly enough, both
read and write events can be triggered together within the same event loop
iteration.  In this case the read event handler is called first and the
write event handler is called after it.

SSL initialization for backend connections happens only in the write event
handler since SSL handshake starts with sending Client Hello.  Previously,
if a backend sent a quick plain text response, it could be parsed by the
read event handler prior to starting SSL handshake on the connection.
The change adds protection against parsing such responses on SSL-enabled
connections.

3 months agoUpdated OpenSSL and PCRE used for win32 builds.
Roman Arutyunyan [Tue, 3 Feb 2026 14:29:43 +0000 (18:29 +0400)]
Updated OpenSSL and PCRE used for win32 builds.

3 months agoOutput chain: clear the last_buf flag unless inherited.
Sergey Kandaurov [Wed, 24 Dec 2025 21:21:52 +0000 (01:21 +0400)]
Output chain: clear the last_buf flag unless inherited.

For instance, the last_buf flag is used in the http proxy module when
creating HTTP/2 requests to indicate the output is closed.  The flag
is inherited in ngx_output_chain() to a destination buffer when reading
the buffered request body.  Then it is used in the proxy output filter
to mark the last HTTP/2 DATA frame with END_STREAM.

The problem happens when reusing the destination buffer, such as to
re-read the buffered request body on next upstream, because this buffer
may contain a dirty last_buf value, which breaks sending HTTP/2 request
body in multiple output filter calls.

The flush and last_in_chain flags are cleared for consistency.

3 months agoProxy: fixed sending HTTP/2 buffered request body on next upstream.
Sergey Kandaurov [Wed, 24 Dec 2025 18:59:40 +0000 (22:59 +0400)]
Proxy: fixed sending HTTP/2 buffered request body on next upstream.

If a buffered request body wasn't fully sent, such as on early upstream
response or limited by flow control, unsent buffers could remain in the
input or busy chains when switching to the next upstream server.  This
resulted either in the invalid request sent or a stalled connection.

The fix is to reset chains similar to ngx_http_upstream_reinit().