This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
Note: monotonic time does not change while VM is suspended
Continue to use real time where required by HTTP protocol, for logging
and for other user-visible instances, such as mod_status, as well as for
external databases and caches.
replace /* fall through */ comment with __attribute_fallthrough__ macro
Note: not adding attribute to code with external origins:
xxhash.h (algo_xxhash.h)
ls-hpack/lshpack.c
so to avoid warnings, may need to compile with -Wno-implicit-fallthrough
(thx flynn)
To reduce log noise, skip warning trace reporting error on backend
socket if the connection has been upgraded, e.g. to websockets
x-ref:
"Socket errors after update to version 1.4.56"
https://redmine.lighttpd.net/issues/3044
When server.stream-request-body = 0 (the default), the entire request
body is collected before engaging the backend. For backends which
require data framing, this could lead to growth in memory use as large
requests were framed all at once.
Prefer to retain large request bodies in temporary files on disk and
frame in portions as write queue to backend drains below a threshold.
x-ref:
"Memory Growth with PUT and full buffered streams"
https://redmine.lighttpd.net/issues/3033
move code from connections-glue.c back into connections.c
move code from connections-glue.c to http-header-glue.c
rename connection_response_reset()
to http_response_reset()
rename connection_handle_read_post_error()
to http_response_reqbody_read_error()
r->con->reqbody_read() replaces connection_handle_read_post_state()
future: might provide different callbacks for request body with
Content-Length versus request body sent via Transfer-Encoding: chunked
(expansion of buffer_string_lenth() inline function and CONST_BUF_LEN()
macro, which always check for NULL, appears to cause the analyzer to
believe that a pointer might be NULL in cases where it otherwise can
not be NULL)
x-ref:
http://clang-analyzer.llvm.org/faq.html
stream request body using HTTP/1.1 Transfer-Encoding: chunked
(Note: if backend proxy target does not support HTTP/1.1,
then do not use server.stream-request-body = 1 or 2)
If not streaming to backend, collect request body
(now supporting Transfer-Encoding: chunked from client
and then sending with Content-Length to backend)
x-ref:
"Lighty returns HTTP 411 Length Required with proxy and streaming requests/reponses body"
https://redmine.lighttpd.net/issues/3006
NB: r->tmp_buf == srv->tmp_buf (pointer is copied for quicker access)
NB: request read and write chunkqueues currently point to connection
chunkqueues; per-request and per-connection chunkqueues are
not distinct from one another
con->read_queue == r->read_queue
con->write_queue == r->write_queue
NB: in the future, a separate connection config may be needed for
connection-level module hooks. Similarly, might need to have
per-request chunkqueues separate from per-connection chunkqueues.
Should probably also have a request_reset() which is distinct from
connection_reset().