diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2023-04-09 00:19:09 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2023-04-29 16:27:58 -0400 |
commit | 5c6b81b7e384c40c82304443d3f362b305a6fdfd (patch) | |
tree | d3bf8d099d3954d96ff5cdb4a2999e0428455377 /src/h2.c | |
parent | 3ec59882a388b8e084695d2ff9917d3acf48d83f (diff) | |
download | lighttpd-git-5c6b81b7e384c40c82304443d3f362b305a6fdfd.tar.gz |
[core] h2_check_timeout()
Diffstat (limited to 'src/h2.c')
-rw-r--r-- | src/h2.c | 79 |
1 files changed, 79 insertions, 0 deletions
@@ -3052,3 +3052,82 @@ h2_upgrade_h2c (request_st * const r, connection * const con) h2_send_goaway_e(con, H2_E_PROTOCOL_ERROR); } } + + +int +h2_check_timeout (connection * const con, const unix_time64_t cur_ts) +{ + h2con * const h2c = con->h2; + request_st * const r = &con->request; + int changed = (r->state != CON_STATE_WRITE); /*(e.g. CON_STATE_ERROR)*/ + + if (!changed) { + if (h2c->rused) { + for (uint32_t i = 0; i < h2c->rused; ++i) { + request_st * const rr = h2c->r[i]; + if (rr->state == CON_STATE_ERROR) { /*(should not happen)*/ + changed = 1; + continue; + } + if (rr->reqbody_length != rr->reqbody_queue.bytes_in) { + /* XXX: should timeout apply if not trying to read on h2con? + * (still applying timeout to catch stuck connections) */ + /* XXX: con->read_idle_ts is not per-request, so timeout + * will not occur if other read activity occurs on h2con + * (future: might keep separate timestamp per-request) */ + if (cur_ts - con->read_idle_ts > rr->conf.max_read_idle) { + /* time - out */ + if (rr->conf.log_request_handling) { + log_error(rr->conf.errh, __FILE__, __LINE__, + "request aborted - read timeout: %d", con->fd); + } + connection_set_state_error(r, CON_STATE_ERROR); + changed = 1; + } + } + + if (rr->state != CON_STATE_READ_POST + && con->write_request_ts != 0) { + /* XXX: con->write_request_ts is not per-request, so timeout + * will not occur if other write activity occurs on h2con + * (future: might keep separate timestamp per-request) */ + if (cur_ts - con->write_request_ts + > r->conf.max_write_idle) { + /*(see comment further down about max_write_idle)*/ + /* time - out */ + if (r->conf.log_timeouts) { + log_error(r->conf.errh, __FILE__, __LINE__, + "NOTE: a request from %s for %.*s timed out " + "after writing %lld bytes. We waited %d seconds. " + "If this is a problem, increase " + "server.max-write-idle", + r->dst_addr_buf->ptr, + BUFFER_INTLEN_PTR(&r->target), + (long long)r->write_queue.bytes_out, + (int)r->conf.max_write_idle); + } + connection_set_state_error(r, CON_STATE_ERROR); + changed = 1; + } + } + } + } + else { + if (cur_ts - con->read_idle_ts > con->keep_alive_idle) { + /* time - out */ + if (r->conf.log_request_handling) { + log_error(r->conf.errh, __FILE__, __LINE__, + "connection closed - keep-alive timeout: %d", + con->fd); + } + connection_set_state(r, CON_STATE_RESPONSE_END); + changed = 1; + } + } + /* process changes before optimistic read of additional HTTP/2 frames */ + if (changed) + con->is_readable = 0; + } + + return changed; +} |