<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/http/v2, branch release-1.23.4</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>HTTP/2: finalize request as bad if header validation fails.</title>
<updated>2023-03-10T03:47:53+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2023-03-10T03:47:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=ff9e426337b84ed1d9ff3bbd17e7d7632c7ba19d'/>
<id>ff9e426337b84ed1d9ff3bbd17e7d7632c7ba19d</id>
<content type='text'>
Similarly to 7192:d5a535774861, this avoids spurious zero statuses
in access.log, and in line with other header-related errors.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Similarly to 7192:d5a535774861, this avoids spurious zero statuses
in access.log, and in line with other header-related errors.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: socket leak with "return 444" in error_page (ticket #2455).</title>
<updated>2023-03-10T03:47:48+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2023-03-10T03:47:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=3c949f7c409e41a7c6fd6edb096281a3e82f85e4'/>
<id>3c949f7c409e41a7c6fd6edb096281a3e82f85e4</id>
<content type='text'>
Similarly to ticket #274 (7354:1812f1d79d84), early request finalization
without calling ngx_http_run_posted_requests() resulted in a connection
hang (a socket leak) if the 400 (Bad Request) error was generated in
ngx_http_v2_state_process_header() due to invalid request headers and
"return 444" was used in error_page 400.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Similarly to ticket #274 (7354:1812f1d79d84), early request finalization
without calling ngx_http_run_posted_requests() resulted in a connection
hang (a socket leak) if the 400 (Bad Request) error was generated in
ngx_http_v2_state_process_header() due to invalid request headers and
"return 444" was used in error_page 400.
</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>HTTP/2: fixed closed_nodes overflow (ticket #1708).</title>
<updated>2022-02-03T19:46:01+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2022-02-03T19:46:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=0a90893da03517a17562feb69b170af0365b2068'/>
<id>0a90893da03517a17562feb69b170af0365b2068</id>
<content type='text'>
With large http2_max_concurrent_streams or http2_max_concurrent_pushes, more
than 255 ngx_http_v2_node_t structures might be allocated, eventually leading
to h2c-&gt;closed_nodes overflow when closing corresponding streams.  This will
in turn result in additional allocations in ngx_http_v2_get_node_by_id().

While mostly harmless, it can result in excessive memory usage by a HTTP/2
connection, notably in configurations with many keepalive_requests allowed.
Fix is to use ngx_uint_t for h2c-&gt;closed_nodes instead of unsigned:8.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With large http2_max_concurrent_streams or http2_max_concurrent_pushes, more
than 255 ngx_http_v2_node_t structures might be allocated, eventually leading
to h2c-&gt;closed_nodes overflow when closing corresponding streams.  This will
in turn result in additional allocations in ngx_http_v2_get_node_by_id().

While mostly harmless, it can result in excessive memory usage by a HTTP/2
connection, notably in configurations with many keepalive_requests allowed.
Fix is to use ngx_uint_t for h2c-&gt;closed_nodes instead of unsigned:8.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: made it possible to flush response headers (ticket #1743).</title>
<updated>2022-02-02T22:44:38+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2022-02-02T22:44:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=a52433a04c58821fd95591e474d35995292f1090'/>
<id>a52433a04c58821fd95591e474d35995292f1090</id>
<content type='text'>
Response headers can be buffered in the SSL buffer.  But stream's fake
connection buffered flag did not reflect this, so any attempts to flush
the buffer without sending additional data were stopped by the write filter.

It does not seem to be possible to reflect this in fc-&gt;buffered though, as
we never known if main connection's c-&gt;buffered corresponds to the particular
stream or not.  As such, fc-&gt;buffered might prevent request finalization
due to sending data on some other stream.

Fix is to implement handling of flush buffers when the c-&gt;need_flush_buf
flag is set, similarly to the existing last buffer handling.  The same
flag is now used for UDP sockets in the stream module instead of explicit
checking of c-&gt;type.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Response headers can be buffered in the SSL buffer.  But stream's fake
connection buffered flag did not reflect this, so any attempts to flush
the buffer without sending additional data were stopped by the write filter.

It does not seem to be possible to reflect this in fc-&gt;buffered though, as
we never known if main connection's c-&gt;buffered corresponds to the particular
stream or not.  As such, fc-&gt;buffered might prevent request finalization
due to sending data on some other stream.

Fix is to implement handling of flush buffers when the c-&gt;need_flush_buf
flag is set, similarly to the existing last buffer handling.  The same
flag is now used for UDP sockets in the stream module instead of explicit
checking of c-&gt;type.
</pre>
</div>
</content>
</entry>
<entry>
<title>Moved Huffman coding out of HTTP/2.</title>
<updated>2021-12-21T04:54:16+00:00</updated>
<author>
<name>Ruslan Ermilov</name>
<email>ru@nginx.com</email>
</author>
<published>2021-12-21T04:54:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=363505e806feebb7ceb1f9edb0e3f75c1253384f'/>
<id>363505e806feebb7ceb1f9edb0e3f75c1253384f</id>
<content type='text'>
ngx_http_v2_huff_decode.c and ngx_http_v2_huff_encode.c are renamed
to ngx_http_huff_decode.c and ngx_http_huff_encode.c.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ngx_http_v2_huff_decode.c and ngx_http_v2_huff_encode.c are renamed
to ngx_http_huff_decode.c and ngx_http_huff_encode.c.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: fixed sendfile() aio handling.</title>
<updated>2021-11-25T19:02:10+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-11-25T19:02:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=83e92a2edd6bf7c6867b653284ac44962c4e33c9'/>
<id>83e92a2edd6bf7c6867b653284ac44962c4e33c9</id>
<content type='text'>
With sendfile() in threads ("aio threads; sendfile on;"), client connection
can block on writing, waiting for sendfile() to complete.  In HTTP/2 this
might result in the request hang, since an attempt to continue processing
in thread event handler will call request's write event handler, which
is usually stopped by ngx_http_v2_send_chain(): it does nothing if there
are no additional data and stream-&gt;queued is set.  Further, HTTP/2 resets
stream's c-&gt;write-&gt;ready to 0 if writing blocks, so just fixing
ngx_http_v2_send_chain() is not enough.

Can be reproduced with test suite on Linux with:

TEST_NGINX_GLOBALS_HTTP="aio threads; sendfile on;" prove h2*.t

The following tests currently fail: h2_keepalive.t, h2_priority.t,
h2_proxy_max_temp_file_size.t, h2.t, h2_trailers.t.

Similarly, sendfile() with AIO preloading on FreeBSD can block as well,
with similar results.  This is, however, harder to reproduce, especially
on modern FreeBSD systems, since sendfile() usually does not return EBUSY.

Fix is to modify ngx_http_v2_send_chain() so it actually tries to send
data to the main connection when called, and to make sure that
c-&gt;write-&gt;ready is set by the relevant event handlers.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With sendfile() in threads ("aio threads; sendfile on;"), client connection
can block on writing, waiting for sendfile() to complete.  In HTTP/2 this
might result in the request hang, since an attempt to continue processing
in thread event handler will call request's write event handler, which
is usually stopped by ngx_http_v2_send_chain(): it does nothing if there
are no additional data and stream-&gt;queued is set.  Further, HTTP/2 resets
stream's c-&gt;write-&gt;ready to 0 if writing blocks, so just fixing
ngx_http_v2_send_chain() is not enough.

Can be reproduced with test suite on Linux with:

TEST_NGINX_GLOBALS_HTTP="aio threads; sendfile on;" prove h2*.t

The following tests currently fail: h2_keepalive.t, h2_priority.t,
h2_proxy_max_temp_file_size.t, h2.t, h2_trailers.t.

Similarly, sendfile() with AIO preloading on FreeBSD can block as well,
with similar results.  This is, however, harder to reproduce, especially
on modern FreeBSD systems, since sendfile() usually does not return EBUSY.

Fix is to modify ngx_http_v2_send_chain() so it actually tries to send
data to the main connection when called, and to make sure that
c-&gt;write-&gt;ready is set by the relevant event handlers.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: removed support for NPN.</title>
<updated>2021-10-15T07:02:15+00:00</updated>
<author>
<name>Vladimir Homutov</name>
<email>vl@nginx.com</email>
</author>
<published>2021-10-15T07:02:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=1db517fb71aed6d6fffc8347086f89eb29b83dea'/>
<id>1db517fb71aed6d6fffc8347086f89eb29b83dea</id>
<content type='text'>
NPN was replaced with ALPN, published as RFC 7301 in July 2014.
It used to negotiate SPDY (and, in transition, HTTP/2).

NPN supported appeared in OpenSSL 1.0.1. It does not work with TLSv1.3 [1].
ALPN is supported since OpenSSL 1.0.2.

The NPN support was dropped in Firefox 53 [2] and Chrome 51 [3].

[1] https://github.com/openssl/openssl/issues/3665.
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1248198
[3] https://www.chromestatus.com/feature/5767920709795840
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
NPN was replaced with ALPN, published as RFC 7301 in July 2014.
It used to negotiate SPDY (and, in transition, HTTP/2).

NPN supported appeared in OpenSSL 1.0.1. It does not work with TLSv1.3 [1].
ALPN is supported since OpenSSL 1.0.2.

The NPN support was dropped in Firefox 53 [2] and Chrome 51 [3].

[1] https://github.com/openssl/openssl/issues/3665.
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1248198
[3] https://www.chromestatus.com/feature/5767920709795840
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: optimized processing of small DATA frames.</title>
<updated>2021-09-06T11:54:50+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-09-06T11:54:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=243469df65fca2a853c6fe32754d1bfe19567cd2'/>
<id>243469df65fca2a853c6fe32754d1bfe19567cd2</id>
<content type='text'>
The request body filter chain is no longer called after processing
a DATA frame.  Instead, we now post a read event to do this.  This
ensures that multiple small DATA frames read during the same event loop
iteration are coalesced together, resulting in much faster processing.

Since rb-&gt;buf can now contain unprocessed data, window update is no
longer sent in ngx_http_v2_state_read_data() in case of flow control
being used due to filter buffering.  Instead, window will be updated
by ngx_http_v2_read_client_request_body_handler() in the posted read
event.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The request body filter chain is no longer called after processing
a DATA frame.  Instead, we now post a read event to do this.  This
ensures that multiple small DATA frames read during the same event loop
iteration are coalesced together, resulting in much faster processing.

Since rb-&gt;buf can now contain unprocessed data, window update is no
longer sent in ngx_http_v2_state_read_data() in case of flow control
being used due to filter buffering.  Instead, window will be updated
by ngx_http_v2_read_client_request_body_handler() in the posted read
event.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/2: fixed timers left after request body reading.</title>
<updated>2021-09-06T11:54:48+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-09-06T11:54:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=584a30b4d51302755c5600892fc293b1586985f7'/>
<id>584a30b4d51302755c5600892fc293b1586985f7</id>
<content type='text'>
Following rb-&gt;filter_need_buffering changes, request body reading is
only finished after the filter chain is called and rb-&gt;last_saved is set.
As such, with r-&gt;request_body_no_buffering, timer on fc-&gt;read is no
longer removed when the last part of the body is received, potentially
resulting in incorrect behaviour.

The fix is to call ngx_http_v2_process_request_body() from the
ngx_http_v2_read_unbuffered_request_body() function instead of
directly calling ngx_http_v2_filter_request_body(), so the timer
is properly removed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Following rb-&gt;filter_need_buffering changes, request body reading is
only finished after the filter chain is called and rb-&gt;last_saved is set.
As such, with r-&gt;request_body_no_buffering, timer on fc-&gt;read is no
longer removed when the last part of the body is received, potentially
resulting in incorrect behaviour.

The fix is to call ngx_http_v2_process_request_body() from the
ngx_http_v2_read_unbuffered_request_body() function instead of
directly calling ngx_http_v2_filter_request_body(), so the timer
is properly removed.
</pre>
</div>
</content>
</entry>
</feed>
