<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/http/ngx_http_upstream.h, branch release-1.29.5</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>Upstream: reinit upstream after reading bad response.</title>
<updated>2026-02-04T15:09:20+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2026-01-28T16:38:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d7a249470b78a155c7548aea5f4eb959dae9fd03'/>
<id>d7a249470b78a155c7548aea5f4eb959dae9fd03</id>
<content type='text'>
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-&gt;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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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-&gt;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.
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: add support for connection level ALPN protocol negotiation.</title>
<updated>2025-12-08T03:49:16+00:00</updated>
<author>
<name>Zhidao HONG</name>
<email>z.hong@f5.com</email>
</author>
<published>2025-07-15T14:54:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=b8492d9c25c34c87419d2ad118fa812fd72da27c'/>
<id>b8492d9c25c34c87419d2ad118fa812fd72da27c</id>
<content type='text'>
This commit is prepared for HTTP/2 and HTTP/3 support.

The ALPN protocol is now set per-connection in
ngx_http_upstream_ssl_init_connection(), allowing proper protocol negotiation
for each individual upstream connection regardless of SSL context sharing.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit is prepared for HTTP/2 and HTTP/3 support.

The ALPN protocol is now set per-connection in
ngx_http_upstream_ssl_init_connection(), allowing proper protocol negotiation
for each individual upstream connection regardless of SSL context sharing.
</pre>
</div>
</content>
</entry>
<entry>
<title>Modules compatibility: increased compat section size.</title>
<updated>2025-10-28T12:00:54+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2025-10-27T12:12:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=65c0b2e7709aa6949747dc2925dc3bcbddc1659f'/>
<id>65c0b2e7709aa6949747dc2925dc3bcbddc1659f</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: fixed reinit request with gRPC and Early Hints.</title>
<updated>2025-06-23T16:12:21+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-06-23T10:55:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=cdf7a9c6cb7f344efc80d790fbacdc1c94ab16e3'/>
<id>cdf7a9c6cb7f344efc80d790fbacdc1c94ab16e3</id>
<content type='text'>
The gRPC module context has connection specific state, which can be lost
after request reinitialization when it comes to processing early hints.

The fix is to do only a portion of u-&gt;reinit_request() implementation
required after processing early hints, now inlined in modules.

Now NGX_HTTP_UPSTREAM_EARLY_HINTS is returned from u-&gt;process_header()
for early hints.  When reading a cached response, this code is mapped
to NGX_HTTP_UPSTREAM_INVALID_HEADER to indicate invalid header format.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The gRPC module context has connection specific state, which can be lost
after request reinitialization when it comes to processing early hints.

The fix is to do only a portion of u-&gt;reinit_request() implementation
required after processing early hints, now inlined in modules.

Now NGX_HTTP_UPSTREAM_EARLY_HINTS is returned from u-&gt;process_header()
for early hints.  When reading a cached response, this code is mapped
to NGX_HTTP_UPSTREAM_INVALID_HEADER to indicate invalid header format.
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: early hints support.</title>
<updated>2025-06-19T06:19:57+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-11-15T04:23:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=662c1dd2a97afd6c7ca09b8f5a74347ee017b86b'/>
<id>662c1dd2a97afd6c7ca09b8f5a74347ee017b86b</id>
<content type='text'>
The change implements processing upstream early hints response in
ngx_http_proxy_module and ngx_http_grpc_module.  A new directive
"early_hints" enables sending early hints to the client.  By default,
sending early hints is disabled.

Example:

    map $http_sec_fetch_mode $early_hints {
        navigate $http2$http3;
    }

    early_hints $early_hints;

    proxy_pass http://example.com;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The change implements processing upstream early hints response in
ngx_http_proxy_module and ngx_http_grpc_module.  A new directive
"early_hints" enables sending early hints to the client.  By default,
sending early hints is disabled.

Example:

    map $http_sec_fetch_mode $early_hints {
        navigate $http2$http3;
    }

    early_hints $early_hints;

    proxy_pass http://example.com;
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: fixed passwords support for dynamic certificates.</title>
<updated>2025-04-10T13:27:45+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-02-05T15:16:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=6c3a9d561271ec451f479a84fbe54c81a63dad2e'/>
<id>6c3a9d561271ec451f479a84fbe54c81a63dad2e</id>
<content type='text'>
Passwords were not preserved in optimized SSL contexts, the bug had
appeared in d791b4aab (1.23.1), as in the following configuration:

    server {
        proxy_ssl_password_file password;
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location /original/ {
            proxy_pass https://u1/;
        }

        location /optimized/ {
            proxy_pass https://u2/;
        }
    }

The fix is to always preserve passwords, by copying to the configuration
pool, if dynamic certificates are used.  This is done as part of merging
"ssl_passwords" configuration.

To minimize the number of copies, a preserved version is then used for
inheritance.  A notable exception is inheritance of preserved empty
passwords to the context with statically configured certificates:

    server {
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location / {
            proxy_pass ...;

            proxy_ssl_certificate example.com.crt;
            proxy_ssl_certificate_key example.com.key;
        }
    }

In this case, an unmodified version (NULL) of empty passwords is set,
to allow reading them from the password prompt on nginx startup.

As an additional optimization, a preserved instance of inherited
configured passwords is set to the previous level, to inherit it
to other contexts:

    server {
        proxy_ssl_password_file password;

        location /1/ {
            proxy_pass https://u1/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }

        location /2/ {
            proxy_pass https://u2/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }
    }
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Passwords were not preserved in optimized SSL contexts, the bug had
appeared in d791b4aab (1.23.1), as in the following configuration:

    server {
        proxy_ssl_password_file password;
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location /original/ {
            proxy_pass https://u1/;
        }

        location /optimized/ {
            proxy_pass https://u2/;
        }
    }

The fix is to always preserve passwords, by copying to the configuration
pool, if dynamic certificates are used.  This is done as part of merging
"ssl_passwords" configuration.

To minimize the number of copies, a preserved version is then used for
inheritance.  A notable exception is inheritance of preserved empty
passwords to the context with statically configured certificates:

    server {
        proxy_ssl_certificate $ssl_server_name.crt;
        proxy_ssl_certificate_key $ssl_server_name.key;

        location / {
            proxy_pass ...;

            proxy_ssl_certificate example.com.crt;
            proxy_ssl_certificate_key example.com.key;
        }
    }

In this case, an unmodified version (NULL) of empty passwords is set,
to allow reading them from the password prompt on nginx startup.

As an additional optimization, a preserved instance of inherited
configured passwords is set to the previous level, to inherit it
to other contexts:

    server {
        proxy_ssl_password_file password;

        location /1/ {
            proxy_pass https://u1/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }

        location /2/ {
            proxy_pass https://u2/;
            proxy_ssl_certificate $ssl_server_name.crt;
            proxy_ssl_certificate_key $ssl_server_name.key;
        }
    }
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: caching certificates and certificate keys with variables.</title>
<updated>2025-01-17T00:37:46+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2024-10-29T14:20:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=454ad0ef33a347eba1a62d18c8fc0498f4dcfd64'/>
<id>454ad0ef33a347eba1a62d18c8fc0498f4dcfd64</id>
<content type='text'>
Caching is enabled with proxy_ssl_certificate_cache and friends.

Co-authored-by: Aleksei Bavshin &lt;a.bavshin@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Caching is enabled with proxy_ssl_certificate_cache and friends.

Co-authored-by: Aleksei Bavshin &lt;a.bavshin@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: construct upstream peers from DNS SRV records.</title>
<updated>2024-11-07T15:57:42+00:00</updated>
<author>
<name>Dmitry Volyntsev</name>
<email>xeioex@nginx.com</email>
</author>
<published>2016-03-17T15:42:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=9fe119b431c957824d7bed75fce47dfbda74ca33'/>
<id>9fe119b431c957824d7bed75fce47dfbda74ca33</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Upstream: re-resolvable servers.</title>
<updated>2024-11-07T15:57:42+00:00</updated>
<author>
<name>Ruslan Ermilov</name>
<email>ru@nginx.com</email>
</author>
<published>2014-02-15T11:12:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=db6870e06dde7ab249e9a41a0e0a76219f82dd8c'/>
<id>db6870e06dde7ab249e9a41a0e0a76219f82dd8c</id>
<content type='text'>
Specifying the upstream server by a hostname together with the
"resolve" parameter will make the hostname to be periodically
resolved, and upstream servers added/removed as necessary.

This requires a "resolver" at the "http" configuration block.

The "resolver_timeout" parameter also affects when the failed
DNS requests will be attempted again.  Responses with NXDOMAIN
will be attempted again in 10 seconds.

Upstream has a configuration generation number that is incremented each
time servers are added/removed to the primary/backup list.  This number
is remembered by the peer.init method, and if peer.get detects a change
in configuration, it returns NGX_BUSY.

Each server has a reference counter.  It is incremented by peer.get and
decremented by peer.free.  When a server is removed, it is removed from
the list of servers and is marked as "zombie".  The memory allocated by
a zombie peer is freed only when its reference count becomes zero.

Co-authored-by: Roman Arutyunyan &lt;arut@nginx.com&gt;
Co-authored-by: Sergey Kandaurov &lt;pluknet@nginx.com&gt;
Co-authored-by: Vladimir Homutov &lt;vl@nginx.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Specifying the upstream server by a hostname together with the
"resolve" parameter will make the hostname to be periodically
resolved, and upstream servers added/removed as necessary.

This requires a "resolver" at the "http" configuration block.

The "resolver_timeout" parameter also affects when the failed
DNS requests will be attempted again.  Responses with NXDOMAIN
will be attempted again in 10 seconds.

Upstream has a configuration generation number that is incremented each
time servers are added/removed to the primary/backup list.  This number
is remembered by the peer.init method, and if peer.get detects a change
in configuration, it returns NGX_BUSY.

Each server has a reference counter.  It is incremented by peer.get and
decremented by peer.free.  When a server is removed, it is removed from
the list of servers and is marked as "zombie".  The memory allocated by
a zombie peer is freed only when its reference count becomes zero.

Co-authored-by: Roman Arutyunyan &lt;arut@nginx.com&gt;
Co-authored-by: Sergey Kandaurov &lt;pluknet@nginx.com&gt;
Co-authored-by: Vladimir Homutov &lt;vl@nginx.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>Proxy: proxy_pass_trailers directive.</title>
<updated>2024-09-13T12:47:56+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2024-09-10T12:48:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=1a64c196a7d43f83a14fec20ce8936e599c92865'/>
<id>1a64c196a7d43f83a14fec20ce8936e599c92865</id>
<content type='text'>
The directive allows to pass upstream response trailers to client.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The directive allows to pass upstream response trailers to client.
</pre>
</div>
</content>
</entry>
</feed>
