Browse Source

[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)
master
Glenn Strauss 2 months ago
parent
commit
39c0c2c3ed
  1. 8
      src/connections.c

8
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) {

Loading…
Cancel
Save