<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/http/ngx_http_request.c, branch release-1.29.3</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>CONNECT method support for HTTP/1.1.</title>
<updated>2025-10-23T14:40:05+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2025-09-23T11:03:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=42ca3a4576a32d0a912b0bba4088b8169f55ab2d'/>
<id>42ca3a4576a32d0a912b0bba4088b8169f55ab2d</id>
<content type='text'>
The change allows modules to use the CONNECT method with HTTP/1.1 requests.
To do so, they need to set the "allow_connect" flag in the core server
configuration.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The change allows modules to use the CONNECT method with HTTP/1.1 requests.
To do so, they need to set the "allow_connect" flag in the core server
configuration.
</pre>
</div>
</content>
</entry>
<entry>
<title>Added $request_port and $is_request_port variables.</title>
<updated>2025-10-23T14:40:05+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2025-09-29T16:47:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=c8c7beb96f61e2251abbc345357116131cf91c22'/>
<id>c8c7beb96f61e2251abbc345357116131cf91c22</id>
<content type='text'>
The $request_port variable contains the port passed by the client in the
request line (for HTTP/1.x) or ":authority" pseudo-header (for HTTP/2 and
HTTP/3).  If the request line contains no host, or ":authority" is missing,
then $request_port is taken from the "Host" header, similar to the $host
variable.

The $is_request_port variable contains ":" if $request_port is non-empty,
and is empty otherwise.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The $request_port variable contains the port passed by the client in the
request line (for HTTP/1.x) or ":authority" pseudo-header (for HTTP/2 and
HTTP/3).  If the request line contains no host, or ":authority" is missing,
then $request_port is taken from the "Host" header, similar to the $host
variable.

The $is_request_port variable contains ":" if $request_port is non-empty,
and is empty otherwise.
</pre>
</div>
</content>
</entry>
<entry>
<title>SNI: support for early ClientHello callback with BoringSSL.</title>
<updated>2025-09-25T15:25:08+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-09-22T15:55:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=7f9ced0ce0d70ae60f46ef3ed759efa75e711db4'/>
<id>7f9ced0ce0d70ae60f46ef3ed759efa75e711db4</id>
<content type='text'>
This brings feature parity with OpenSSL after the previous change,
making it possible to set SSL protocols per virtual server.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This brings feature parity with OpenSSL after the previous change,
making it possible to set SSL protocols per virtual server.
</pre>
</div>
</content>
</entry>
<entry>
<title>SNI: using the ClientHello callback.</title>
<updated>2025-09-25T15:25:08+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-01-27T20:53:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=0373fe5d98c1515640e74fa6f4d32fac1f1d3ab2'/>
<id>0373fe5d98c1515640e74fa6f4d32fac1f1d3ab2</id>
<content type='text'>
The change introduces an SNI based virtual server selection during
early ClientHello processing.  The callback is available since
OpenSSL 1.1.1; for older OpenSSL versions, the previous behaviour
is kept.

Using the ClientHello callback sets a reasonable processing order
for the "server_name" TLS extension.  Notably, session resumption
decision now happens after applying server configuration chosen by
SNI, useful with enabled verification of client certificates, which
brings consistency with BoringSSL behaviour.  The change supersedes
and reverts a fix made in 46b9f5d38 for TLSv1.3 resumed sessions.

In addition, since the callback is invoked prior to the protocol
version negotiation, this makes it possible to set "ssl_protocols"
on a per-virtual server basis.

To keep the $ssl_server_name variable working with TLSv1.2 resumed
sessions, as previously fixed in fd97b2a80, a limited server name
callback is preserved in order to acknowledge the extension.

Note that to allow third-party modules to properly chain the call to
ngx_ssl_client_hello_callback(), the servername callback function is
passed through exdata.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The change introduces an SNI based virtual server selection during
early ClientHello processing.  The callback is available since
OpenSSL 1.1.1; for older OpenSSL versions, the previous behaviour
is kept.

Using the ClientHello callback sets a reasonable processing order
for the "server_name" TLS extension.  Notably, session resumption
decision now happens after applying server configuration chosen by
SNI, useful with enabled verification of client certificates, which
brings consistency with BoringSSL behaviour.  The change supersedes
and reverts a fix made in 46b9f5d38 for TLSv1.3 resumed sessions.

In addition, since the callback is invoked prior to the protocol
version negotiation, this makes it possible to set "ssl_protocols"
on a per-virtual server basis.

To keep the $ssl_server_name variable working with TLSv1.2 resumed
sessions, as previously fixed in fd97b2a80, a limited server name
callback is preserved in order to acknowledge the extension.

Note that to allow third-party modules to properly chain the call to
ngx_ssl_client_hello_callback(), the servername callback function is
passed through exdata.
</pre>
</div>
</content>
</entry>
<entry>
<title>Made ngx_http_process_request_header() static again.</title>
<updated>2025-08-03T06:07:07+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-07-23T11:56:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=4d857aaf435975d3c34e41d7a9cb50c0f87879ec'/>
<id>4d857aaf435975d3c34e41d7a9cb50c0f87879ec</id>
<content type='text'>
The function contains mostly HTTP/1.x specific request processing,
which has no use in other protocols.  After the previous change in
HTTP/2, it can now be hidden.

This is an API change.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The function contains mostly HTTP/1.x specific request processing,
which has no use in other protocols.  After the previous change in
HTTP/2, it can now be hidden.

This is an API change.
</pre>
</div>
</content>
</entry>
<entry>
<title>SNI: added restriction for TLSv1.3 cross-SNI session resumption.</title>
<updated>2025-02-05T16:11:42+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-01-22T14:55:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=46b9f5d389447b3b822ea71f5ac86ebc316c2975'/>
<id>46b9f5d389447b3b822ea71f5ac86ebc316c2975</id>
<content type='text'>
In OpenSSL, session resumption always happens in the default SSL context,
prior to invoking the SNI callback.  Further, unlike in TLSv1.2 and older
protocols, SSL_get_servername() returns values received in the resumption
handshake, which may be different from the value in the initial handshake.
Notably, this makes the restriction added in b720f650b insufficient for
sessions resumed with different SNI server name.

Considering the example from b720f650b, previously, a client was able to
request example.org by presenting a certificate for example.org, then to
resume and request example.com.

The fix is to reject handshakes resumed with a different server name, if
verification of client certificates is enabled in a corresponding server
configuration.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In OpenSSL, session resumption always happens in the default SSL context,
prior to invoking the SNI callback.  Further, unlike in TLSv1.2 and older
protocols, SSL_get_servername() returns values received in the resumption
handshake, which may be different from the value in the initial handshake.
Notably, this makes the restriction added in b720f650b insufficient for
sessions resumed with different SNI server name.

Considering the example from b720f650b, previously, a client was able to
request example.org by presenting a certificate for example.org, then to
resume and request example.com.

The fix is to reject handshakes resumed with a different server name, if
verification of client certificates is enabled in a corresponding server
configuration.
</pre>
</div>
</content>
</entry>
<entry>
<title>Added "keepalive_min_timeout" directive.</title>
<updated>2025-02-05T10:08:01+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2025-01-15T08:42:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=22a2a225ba87029f0e7bbc09a80ff7cdad23399d'/>
<id>22a2a225ba87029f0e7bbc09a80ff7cdad23399d</id>
<content type='text'>
The directive sets a timeout during which a keepalive connection will
not be closed by nginx for connection reuse or graceful shutdown.

The change allows clients that send multiple requests over the same
connection without delay or with a small delay between them, to avoid
receiving a TCP RST in response to one of them.  This excludes network
issues and non-graceful shutdown.  As a side-effect, it also addresses
the TCP reset problem described in RFC 9112, Section 9.6, when the last
sent HTTP response could be damaged by a followup TCP RST.  It is important
for non-idempotent requests, which cannot be retried by client.

It is not recommended to set keepalive_min_timeout to large values as
this can introduce an additional delay during graceful shutdown and may
restrict nginx from effective connection reuse.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The directive sets a timeout during which a keepalive connection will
not be closed by nginx for connection reuse or graceful shutdown.

The change allows clients that send multiple requests over the same
connection without delay or with a small delay between them, to avoid
receiving a TCP RST in response to one of them.  This excludes network
issues and non-graceful shutdown.  As a side-effect, it also addresses
the TCP reset problem described in RFC 9112, Section 9.6, when the last
sent HTTP response could be damaged by a followup TCP RST.  It is important
for non-idempotent requests, which cannot be retried by client.

It is not recommended to set keepalive_min_timeout to large values as
this can introduce an additional delay during graceful shutdown and may
restrict nginx from effective connection reuse.
</pre>
</div>
</content>
</entry>
<entry>
<title>SSL: 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-29T12:25:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=0e756d67aa1e42e3b1b360936eb4d6c06bced2c1'/>
<id>0e756d67aa1e42e3b1b360936eb4d6c06bced2c1</id>
<content type='text'>
A new directive "ssl_certificate_cache max=N [valid=time] [inactive=time]"
enables caching of SSL certificate chain and secret key objects specified
by "ssl_certificate" and "ssl_certificate_key" directives with variables.

Co-authored-by: Aleksei Bavshin &lt;a.bavshin@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A new directive "ssl_certificate_cache max=N [valid=time] [inactive=time]"
enables caching of SSL certificate chain and secret key objects specified
by "ssl_certificate" and "ssl_certificate_key" directives with variables.

Co-authored-by: Aleksei Bavshin &lt;a.bavshin@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fixed request termination with AIO and subrequests (ticket #2555).</title>
<updated>2024-01-30T00:20:05+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2024-01-30T00:20:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=c251961c4186ce93cf6eb3c99bf5b7114535d490'/>
<id>c251961c4186ce93cf6eb3c99bf5b7114535d490</id>
<content type='text'>
When a request was terminated due to an error via ngx_http_terminate_request()
while an AIO operation was running in a subrequest, various issues were
observed.  This happened because ngx_http_request_finalizer() was only set
in the subrequest where ngx_http_terminate_request() was called, but not
in the subrequest where the AIO operation was running.  After completion
of the AIO operation normal processing of the subrequest was resumed, leading
to issues.

In particular, in case of the upstream module, termination of the request
called upstream cleanup, which closed the upstream connection.  Attempts to
further work with the upstream connection after AIO operation completion
resulted in segfaults in ngx_ssl_recv(), "readv() failed (9: Bad file
descriptor) while reading upstream" errors, or socket leaks.

In ticket #2555, issues were observed with the following configuration
with cache background update (with thread writing instrumented to
introduce a delay, when a client closes the connection during an update):

    location = /background-and-aio-write {
        proxy_pass ...
        proxy_cache one;
        proxy_cache_valid 200 1s;
        proxy_cache_background_update on;
        proxy_cache_use_stale updating;
        aio threads;
        aio_write on;
        limit_rate 1000;
    }

Similarly, the same issue can be seen with SSI, and can be caused by
errors in subrequests, such as in the following configuration
(where "/proxy" uses AIO, and "/sleep" returns 444 after some delay,
causing request termination):

    location = /ssi-active-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/proxy" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Or the same with both AIO operation and the error in non-active subrequests
(which needs slightly different handling, see below):

    location = /ssi-non-active-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static" --&gt;
                   &lt;!--#include virtual="/proxy" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Similarly, issues can be observed with just static files.  However,
with static files potential impact is limited due to timeout safeguards
in ngx_http_writer(), and the fact that c-&gt;error is set during request
termination.

In a simple configuration with an AIO operation in the active subrequest,
such as in the following configuration, the connection is closed right
after completion of the AIO operation anyway, since ngx_http_writer()
tries to write to the connection and fails due to c-&gt;error set:

    location = /ssi-active-static-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static-aio" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

In the following configuration, with an AIO operation in a non-active
subrequest, the connection is closed only after send_timeout expires:

    location = /ssi-non-active-static-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static" --&gt;
                   &lt;!--#include virtual="/static-aio" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Fix is to introduce r-&gt;main-&gt;terminated flag, which is to be checked
by AIO event handlers when the r-&gt;main-&gt;blocked counter is decremented.
When the flag is set, handlers are expected to wake up the connection
instead of the subrequest (which might be already cleaned up).

Additionally, now ngx_http_request_finalizer() is always set in the
active subrequest, so waking up the connection properly finalizes the
request even if termination happened in a non-active subrequest.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When a request was terminated due to an error via ngx_http_terminate_request()
while an AIO operation was running in a subrequest, various issues were
observed.  This happened because ngx_http_request_finalizer() was only set
in the subrequest where ngx_http_terminate_request() was called, but not
in the subrequest where the AIO operation was running.  After completion
of the AIO operation normal processing of the subrequest was resumed, leading
to issues.

In particular, in case of the upstream module, termination of the request
called upstream cleanup, which closed the upstream connection.  Attempts to
further work with the upstream connection after AIO operation completion
resulted in segfaults in ngx_ssl_recv(), "readv() failed (9: Bad file
descriptor) while reading upstream" errors, or socket leaks.

In ticket #2555, issues were observed with the following configuration
with cache background update (with thread writing instrumented to
introduce a delay, when a client closes the connection during an update):

    location = /background-and-aio-write {
        proxy_pass ...
        proxy_cache one;
        proxy_cache_valid 200 1s;
        proxy_cache_background_update on;
        proxy_cache_use_stale updating;
        aio threads;
        aio_write on;
        limit_rate 1000;
    }

Similarly, the same issue can be seen with SSI, and can be caused by
errors in subrequests, such as in the following configuration
(where "/proxy" uses AIO, and "/sleep" returns 444 after some delay,
causing request termination):

    location = /ssi-active-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/proxy" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Or the same with both AIO operation and the error in non-active subrequests
(which needs slightly different handling, see below):

    location = /ssi-non-active-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static" --&gt;
                   &lt;!--#include virtual="/proxy" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Similarly, issues can be observed with just static files.  However,
with static files potential impact is limited due to timeout safeguards
in ngx_http_writer(), and the fact that c-&gt;error is set during request
termination.

In a simple configuration with an AIO operation in the active subrequest,
such as in the following configuration, the connection is closed right
after completion of the AIO operation anyway, since ngx_http_writer()
tries to write to the connection and fails due to c-&gt;error set:

    location = /ssi-active-static-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static-aio" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

In the following configuration, with an AIO operation in a non-active
subrequest, the connection is closed only after send_timeout expires:

    location = /ssi-non-active-static-boom {
        ssi on;
        ssi_types *;
        return 200 '
                   &lt;!--#include virtual="/static" --&gt;
                   &lt;!--#include virtual="/static-aio" --&gt;
                   &lt;!--#include virtual="/sleep" --&gt;
                   ';
        limit_rate 1000;
    }

Fix is to introduce r-&gt;main-&gt;terminated flag, which is to be checked
by AIO event handlers when the r-&gt;main-&gt;blocked counter is decremented.
When the flag is set, handlers are expected to wake up the connection
instead of the subrequest (which might be already cleaned up).

Additionally, now ngx_http_request_finalizer() is always set in the
active subrequest, so waking up the connection properly finalizes the
request even if termination happened in a non-active subrequest.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP: uniform checks in ngx_http_alloc_large_header_buffer().</title>
<updated>2023-11-29T08:13:05+00:00</updated>
<author>
<name>Vladimir Khomutov</name>
<email>vl@wbsrv.ru</email>
</author>
<published>2023-11-29T08:13:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d8fa024ef1527a9aefbb52bedd70fa4449203488'/>
<id>d8fa024ef1527a9aefbb52bedd70fa4449203488</id>
<content type='text'>
If URI is not fully parsed yet, some pointers are not set.  As a result,
the calculation of "new + (ptr - old)" expression is flawed.

According to C11, 6.5.6 Additive operators, p.9:

: When two pointers are subtracted, both shall point to elements
: of the same array object, or one past the last element of the
: array object

Since "ptr" is not set, subtraction leads to undefined behaviour, because
"ptr" and "old" are not in the same buffer (i.e. array objects).

Prodded by GCC undefined behaviour sanitizer.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If URI is not fully parsed yet, some pointers are not set.  As a result,
the calculation of "new + (ptr - old)" expression is flawed.

According to C11, 6.5.6 Additive operators, p.9:

: When two pointers are subtracted, both shall point to elements
: of the same array object, or one past the last element of the
: array object

Since "ptr" is not set, subtraction leads to undefined behaviour, because
"ptr" and "old" are not in the same buffer (i.e. array objects).

Prodded by GCC undefined behaviour sanitizer.
</pre>
</div>
</content>
</entry>
</feed>
