diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-09-26 18:03:00 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-10-01 06:39:47 -0400 |
commit | 39c0c2c3edc27706297d84d118f87d5afefa3341 (patch) | |
tree | cc55007374b97f9543548f3aedd56b4e6fd4d39e | |
parent | ed2c6983007c52cab1d903d29222f27f53eb5d86 (diff) | |
download | lighttpd-git-39c0c2c3edc27706297d84d118f87d5afefa3341.tar.gz |
[core] cap size of data framed for HTTP/2 response
cap size of data framed for HTTP/2 response until more data sent to
client
make sure to reschedule connection in job queue if max_bytes reached
and then the entire con->write_queue was flushed to network, or else
there is a chance the request may not get rescheduled (and then will
timeout) if the request is completed from the backend and there is
no other traffic or streams to trigger connection processing.
(check con->write_queue > 8k rather than empty from last round,
since small frames such as connection preface may have been added
this round while processing con->read_queue)
-rw-r--r-- | src/connections.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/connections.c b/src/connections.c index 5639d3e7..43f8c343 100644 --- a/src/connections.c +++ b/src/connections.c @@ -1242,6 +1242,10 @@ connection_state_machine_h2 (request_st * const h2r, connection * const con) ? connection_write_throttle(con, MAX_WRITE_LIMIT) : 0; const off_t fsize = (off_t)h2c->s_max_frame_size; + const off_t cqlen = chunkqueue_length(con->write_queue); + if (cqlen > 8192 && max_bytes > 65536) max_bytes = 65536; + max_bytes -= cqlen; + if (max_bytes < 0) max_bytes = 0; /* XXX: to avoid buffer bloat due to staging too much data in * con->write_queue, consider setting limit on how much is staged @@ -1314,6 +1318,8 @@ connection_state_machine_h2 (request_st * const h2r, connection * const con) connection_request_end_h2(h2r, con); } } + + if (0 == max_bytes) resched |= 2; } if (h2c->sent_goaway > 0 && h2c->rused) { @@ -1339,6 +1345,8 @@ connection_state_machine_h2 (request_st * const h2r, connection * const con) if (chunkqueue_is_empty(con->write_queue) && 0 == h2c->rused && h2c->sent_goaway) connection_set_state(h2r, CON_STATE_RESPONSE_END); + else if (resched & 2) + resched = (resched & 1) | (chunkqueue_is_empty(con->write_queue)); } if (h2r->state == CON_STATE_WRITE) { |