h2: avoid sending tiny DATA frames when h2 window is tiny
and a larger amount of data is pending to be sent;
wait for slightly larger window to be available
note: must temporarily disable this when running h2spec since some
h2spec tests expect 1-byte DATA frame, not a deferred response
Note this may slow down uploads due to delay in sending WINDOW_UPDATE
smaller than the default max frame size (16384), but as a trade-off
this aims to reduce degenerative behavior from clients sending an
increasing number of tiny DATA frames. The default 65535 value for
SETTINGS_INITIAL_WINDOW_SIZE (which lighttpd immediately increases to
65536) is larger than 16384, so deferring small updates should not
exhaust the window (from lighttpd's perspective).
x-ref:
"Slow upload / Increase CPU/Memory usage with HTTP/2 enabled"
https://redmine.lighttpd.net/issues/3089
"libnghttp2 degenerative behavior possible when HTTP/2 window size exhausted"
https://github.com/nghttp2/nghttp2/issues/1722
Increase stream window size to 64k (from default 64k-1)
Increase session window size to 256k (from default 64k-1)
(multiple of SETTINGS_MAX_FRAME_SIZE (default 16k))
(rely on TCP window scaling and TCP congestion control
to manage client sending too much data)
Window size as multiple of SETTINGS_MAX_FRAME_SIZE (default 16k) may be
friendlier to client buffer management and more efficient for uploading.
Window sizes are not increased to arbitrarily large numbers as the
HTTP/2 flow control may be useful to help simplistic/naive clients
avoid symptoms of buffer bloat.
Bandwidth delay product on high bandwidth, high latency links may be
large, so increasing window sizes may increase performance. However,
lighttpd code does not check actual per-connection RTT or kernel
socket buffer sizes. 256k chosen as session window size, and 192k as
stream window size.
Above changes avoid degenerative behavior from the widely deployed
libnghttp2 which may devolve to sending 1 byte at a time in some cases.
https://redmine.lighttpd.net/issues/3089
x-ref:
"Slow upload / Increase CPU/Memory usage with HTTP/2 enabled"
https://redmine.lighttpd.net/issues/3089
Delivering HTTP/2 upload speed improvements
https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
alternative way of handling PROPFIND on collection where the request was
made without a trailing slash. Instead of sending 308 redirect in some
cases, set Content-Location response header *and* treat as if request
had been made with trailing slash on the collection for PROPFIND and
PROPPATCH.
https://www.rfc-editor.org/rfc/rfc4918#section-5.2
There is a standing convention that when a collection is referred to
by its name without a trailing slash, the server MAY handle the
request as if the trailing slash were present. In this case, it
SHOULD return a Content-Location header in the response, pointing to
the URL ending with the "/".
x-ref:
"The previous workaround for GVFS is breaking the new version of GVFS"
https://redmine.lighttpd.net/boards/2/topics/10468
HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)
https://www.rfc-editor.org/rfc/rfc4918#section-5.2
Since lighttpd 1.4.56, an oversight in config processing missed
setting explicitly p->conf.ssl_enabled = 0 in network.c when
initializing conditions. When ssl.engine = "enable" in lighttpd.conf
global scope, the missing reset in network.c required non-TLS ports
(e.g. $SERVER["socket"] == ":80") to contain ssl.engine = "disable"
in order for requests to those ports to be served rather than erroring.
(This error was discovered during collaboration with jens-maus in
https://github.com/jens-maus/RaspberryMatic/pull/1847)
There have been zero other instances of this error reported since the
release of lighttpd 1.4.56 in Nov 2020.
Therefore, having ssl.engine = "enable" inherited from the global scope
is unlikely to have any widespread impact in practice, and enabling
ssl.engine = "enable" (along with TLS certificate configuration) is now
recommended as default. When ssl.engine = "enable" in the global scope,
ssl.engine = "disable" should be specified in those $SERVER["socket"]
conditions where clear-text is desired.
translate MIME type "application/javascript" to "text/javascript"
(if required, type may still be overwritten by mod_setenv or mod_magnet)
x-ref:
"Updates to ECMAScript Media Types"
https://www.rfc-editor.org/rfc/rfc9239
(thx sparlane)
failing error handler produced no output and POLLRDHUP received with
POLLIN.
commit dd23fcb2 changed return value from HANDER_FINISHED to
HANDLER_GO_ON when introducing cgi_process_rd_revents(), and POLLRDHUP
case which previously fell through needed to continue to return
HANDLER_FINISHED after calling cgi_connection_close()
x-ref:
"fall-back with cgi error handler no longer works"
https://redmine.lighttpd.net/issues/3157
fix logic for If-None-Match: * test on non-existent entity
(regression in lighttpd 1.4.64)
If-None-Match: * should not fail on a non-existent entity,
as it may be used to make the request conditional on the
origin server having no current representation of the entity.
(see If-None-Match in RFC2616 and RFC7232)
(This logic had been changed in lighttpd 1.4.64 in
commit 8a535e7e06
when allowing bogus, non-'*' If-None-Match etags
for non-existent entities to not-match (and pass the check)
server.feature-flags += ("server.metrics-high-precision" => "enable")
(default: "disable")
enables high-resolution timestamps,
currently used for request start time
This is automatically enabled if mod_accesslog log record format uses
high-resolution format specifiers in the template, but this feature
needs to be enabled if that is not the case and a high-resolution
request start time is desired for use in lua scripts run by mod_magnet,
e.g. to measure time-to-first-byte
https://wiki.lighttpd.net/AbsoLUAtion#Time-to-First-Byte
read-only access to r->server_name for coverage
setting r.req_attr["uri.authority"] in lua sets both r->uri.authority
and points r->server_name to r->uri.authority, and there is not an
obvious (to me) need to be able to set r->server_name separately.
(r->server_name might be set in lighttpd.conf, or else is the same as
r->uri.authority, unless modified by mod_simple_vhost default_host)
encapsulate accounting calculations in
http_request_stats_bytes_in()
http_request_stats_bytes_out()
more accurate accounting for HTTP/1.1 bytes_in on keep-alive requests
(affects case where client pipelines HTTP/1.1 requests)
remove con->bytes_read and con->bytes_written
(no longer needed since request_st was split from connection struct
and request bytes_read_ckpt and bytes_written_ckpt are maintained
for HTTP/1.x bytes_in and bytes_out accounting. Also, further back,
chunkqueue internal accounting was simplified to maintain bytes_in
and bytes_out to always match chunkqueue length)
deprecate lighty.r.req_attr["response.*] which returned strings
These experimental interfaces were added in lighttpd 1.4.56
along with addition of config magnet.attract-response-start-to = "...",
so this only affects new users of experimental interfaces in a new hook
deprecated experimental interfaces will be removed in next lighttpd rel
replacements:
r.req_attr["response.http-status"] -> r.req_item.http_status -- (int)
r.req_attr["response.body-length"] -> r.resp_body.len -- (int)
r.req_attr["response.body"] -> r.resp_body.get -- (str)
lighty.r.req_item.keep_alive
Allow lua scripts to set to 0 or -1. Setting to -1 might be used when
rejecting authentication, and this value will cause lighttpd to delay
the 401 Unauthorized response if the server feature is enabled (default)
server.feature-flags += ("auth.delay-invalid-creds" => "enable")