<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/http/ngx_http_request.h, branch release-1.29.3</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<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>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>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>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: removed unused r-&gt;port_start and r-&gt;port_end.</title>
<updated>2023-11-28T09:57:14+00:00</updated>
<author>
<name>Vladimir Khomutov</name>
<email>vl@wbsrv.ru</email>
</author>
<published>2023-11-28T09:57:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=0db94ba96a00ebfc4a3c55af8eaaf20f971a7c4c'/>
<id>0db94ba96a00ebfc4a3c55af8eaaf20f971a7c4c</id>
<content type='text'>
Neither r-&gt;port_start nor r-&gt;port_end were ever used.

The r-&gt;port_end is set by the parser, though it was never used by
the following code (and was never usable, since not copied by the
ngx_http_alloc_large_header_buffer() without r-&gt;port_start set).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Neither r-&gt;port_start nor r-&gt;port_end were ever used.

The r-&gt;port_end is set by the parser, though it was never used by
the following code (and was never usable, since not copied by the
ngx_http_alloc_large_header_buffer() without r-&gt;port_start set).
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/3: postponed session creation to init() callback.</title>
<updated>2023-09-14T10:13:43+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2023-09-14T10:13:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=26e606a6bcdfa4001bfb6bd24612e8aafa6513b2'/>
<id>26e606a6bcdfa4001bfb6bd24612e8aafa6513b2</id>
<content type='text'>
Now the session object is assigned to c-&gt;data while ngx_http_connection_t
object is referenced by its http_connection field, similar to
ngx_http_v2_connection_t and ngx_http_request_t.

The change allows to eliminate v3_session field from ngx_http_connection_t.
The field was under NGX_HTTP_V3 macro, which was a source of binary
compatibility problems when nginx/module is build with/without HTTP/3 support.

Postponing is essential since c-&gt;data should retain the reference to
ngx_http_connection_t object throughout QUIC handshake, because SSL callbacks
ngx_http_ssl_servername() and ngx_http_ssl_alpn_select() rely on this.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now the session object is assigned to c-&gt;data while ngx_http_connection_t
object is referenced by its http_connection field, similar to
ngx_http_v2_connection_t and ngx_http_request_t.

The change allows to eliminate v3_session field from ngx_http_connection_t.
The field was under NGX_HTTP_V3 macro, which was a source of binary
compatibility problems when nginx/module is build with/without HTTP/3 support.

Postponing is essential since c-&gt;data should retain the reference to
ngx_http_connection_t object throughout QUIC handshake, because SSL callbacks
ngx_http_ssl_servername() and ngx_http_ssl_alpn_select() rely on this.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merged with the default branch.</title>
<updated>2022-06-22T14:34:58+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2022-06-22T14:34:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=c64e2ec1e94974193c286b63db4f58e6e499f5cb'/>
<id>c64e2ec1e94974193c286b63db4f58e6e499f5cb</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Reworked multi headers to use linked lists.</title>
<updated>2022-05-30T18:25:33+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2022-05-30T18:25:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=3aef1d693f3cc431563a7e6a6aba6a34e5290f03'/>
<id>3aef1d693f3cc431563a7e6a6aba6a34e5290f03</id>
<content type='text'>
Multi headers are now using linked lists instead of arrays.  Notably,
the following fields were changed: r-&gt;headers_in.cookies (renamed
to r-&gt;headers_in.cookie), r-&gt;headers_in.x_forwarded_for,
r-&gt;headers_out.cache_control, r-&gt;headers_out.link, u-&gt;headers_in.cache_control
u-&gt;headers_in.cookies (renamed to u-&gt;headers_in.set_cookie).

The r-&gt;headers_in.cookies and u-&gt;headers_in.cookies fields were renamed
to r-&gt;headers_in.cookie and u-&gt;headers_in.set_cookie to match header names.

The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines()
functions were changed accordingly.

With this change, multi headers are now essentially equivalent to normal
headers, and following changes will further make them equivalent.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Multi headers are now using linked lists instead of arrays.  Notably,
the following fields were changed: r-&gt;headers_in.cookies (renamed
to r-&gt;headers_in.cookie), r-&gt;headers_in.x_forwarded_for,
r-&gt;headers_out.cache_control, r-&gt;headers_out.link, u-&gt;headers_in.cache_control
u-&gt;headers_in.cookies (renamed to u-&gt;headers_in.set_cookie).

The r-&gt;headers_in.cookies and u-&gt;headers_in.cookies fields were renamed
to r-&gt;headers_in.cookie and u-&gt;headers_in.set_cookie to match header names.

The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines()
functions were changed accordingly.

With this change, multi headers are now essentially equivalent to normal
headers, and following changes will further make them equivalent.
</pre>
</div>
</content>
</entry>
<entry>
<title>FastCGI: combining headers with identical names (ticket #1724).</title>
<updated>2022-05-30T18:25:27+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2022-05-30T18:25:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d8a7c653e4b8e842c947c0a550a7bc5a7812058a'/>
<id>d8a7c653e4b8e842c947c0a550a7bc5a7812058a</id>
<content type='text'>
FastCGI responder is expected to receive CGI/1.1 environment variables
in the parameters (see section "6.2 Responder" of the FastCGI specification).
Obviously enough, there cannot be multiple environment variables with
the same name.

Further, CGI specification (RFC 3875, section "4.1.18. Protocol-Specific
Meta-Variables") explicitly requires to combine headers: "If multiple
header fields with the same field-name are received then the server MUST
rewrite them as a single value having the same semantics".
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
FastCGI responder is expected to receive CGI/1.1 environment variables
in the parameters (see section "6.2 Responder" of the FastCGI specification).
Obviously enough, there cannot be multiple environment variables with
the same name.

Further, CGI specification (RFC 3875, section "4.1.18. Protocol-Specific
Meta-Variables") explicitly requires to combine headers: "If multiple
header fields with the same field-name are received then the server MUST
rewrite them as a single value having the same semantics".
</pre>
</div>
</content>
</entry>
<entry>
<title>Added r-&gt;response_sent flag.</title>
<updated>2021-09-30T14:14:42+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2021-09-30T14:14:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=b6b2a45fb6824185889373cc0af070c4a90c1b4a'/>
<id>b6b2a45fb6824185889373cc0af070c4a90c1b4a</id>
<content type='text'>
The flag indicates that the entire response was sent to the socket up to the
last_buf flag.  The flag is only usable for protocol implementations that call
ngx_http_write_filter() from header filter, such as HTTP/1.x and HTTP/3.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The flag indicates that the entire response was sent to the socket up to the
last_buf flag.  The flag is only usable for protocol implementations that call
ngx_http_write_filter() from header filter, such as HTTP/1.x and HTTP/3.
</pre>
</div>
</content>
</entry>
</feed>
