|
|
|
@ -921,47 +921,10 @@ static void server_sockets_close (server *srv) {
|
|
|
|
|
srv->sockets_disabled = 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__attribute_cold__
|
|
|
|
|
static void server_graceful_shutdown_maint (server *srv) {
|
|
|
|
|
connections *conns = srv->conns;
|
|
|
|
|
for (size_t ndx = 0; ndx < conns->used; ++ndx) {
|
|
|
|
|
connection * const con = conns->ptr[ndx];
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
if (con->state == CON_STATE_CLOSE) {
|
|
|
|
|
/* reduce remaining linger timeout to be
|
|
|
|
|
* (from zero) *up to* one more second, but no more */
|
|
|
|
|
if (HTTP_LINGER_TIMEOUT > 1)
|
|
|
|
|
con->close_timeout_ts -= (HTTP_LINGER_TIMEOUT - 1);
|
|
|
|
|
if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (con->state == CON_STATE_READ && con->request_count > 1
|
|
|
|
|
&& chunkqueue_is_empty(con->read_queue)) {
|
|
|
|
|
/* close connections in keep-alive waiting for next request */
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
con->keep_alive = 0; /* disable keep-alive */
|
|
|
|
|
|
|
|
|
|
con->conf.kbytes_per_second = 0; /* disable rate limit */
|
|
|
|
|
con->conf.global_kbytes_per_second = 0; /* disable rate limit */
|
|
|
|
|
if (con->traffic_limit_reached) {
|
|
|
|
|
con->traffic_limit_reached = 0;
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
|
connection_state_machine(srv, con);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__attribute_cold__
|
|
|
|
|
static void server_graceful_state (server *srv) {
|
|
|
|
|
|
|
|
|
|
if (!srv_shutdown) server_graceful_shutdown_maint(srv);
|
|
|
|
|
if (!srv_shutdown) connection_graceful_shutdown_maint(srv);
|
|
|
|
|
|
|
|
|
|
if (!oneshot_fd
|
|
|
|
|
&& (2 == srv->sockets_disabled || 3 == srv->sockets_disabled)) return;
|
|
|
|
@ -1831,7 +1794,6 @@ static int server_handle_sighup (server * const srv) {
|
|
|
|
|
|
|
|
|
|
__attribute_noinline__
|
|
|
|
|
static void server_handle_sigalrm (server * const srv, time_t min_ts, time_t last_active_ts) {
|
|
|
|
|
connections *conns = srv->conns;
|
|
|
|
|
handler_t r;
|
|
|
|
|
|
|
|
|
|
switch(r = plugins_call_handle_trigger(srv)) {
|
|
|
|
@ -1877,98 +1839,8 @@ static void server_handle_sigalrm (server * const srv, time_t min_ts, time_t las
|
|
|
|
|
srv->config_storage[i]->global_bytes_per_second_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
/* if graceful_shutdown, accelerate cleanup of recently completed request/responses */
|
|
|
|
|
if (graceful_shutdown && !srv_shutdown) server_graceful_shutdown_maint(srv);
|
|
|
|
|
/**
|
|
|
|
|
* check all connections for timeouts
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
for (size_t ndx = 0; ndx < conns->used; ++ndx) {
|
|
|
|
|
connection * const con = conns->ptr[ndx];
|
|
|
|
|
const int waitevents = fdevent_fdnode_interest(con->fdn);
|
|
|
|
|
int changed = 0;
|
|
|
|
|
int t_diff;
|
|
|
|
|
|
|
|
|
|
if (con->state == CON_STATE_CLOSE) {
|
|
|
|
|
if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if (waitevents & FDEVENT_IN) {
|
|
|
|
|
if (con->request_count == 1 || con->state != CON_STATE_READ) { /* e.g. CON_STATE_READ_POST || CON_STATE_WRITE */
|
|
|
|
|
if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
|
|
|
|
|
/* time - out */
|
|
|
|
|
if (con->conf.log_request_handling) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"connection closed - read timeout:", con->fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
|
|
|
|
|
/* time - out */
|
|
|
|
|
if (con->conf.log_request_handling) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"connection closed - keep-alive timeout:", con->fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* max_write_idle timeout currently functions as backend timeout,
|
|
|
|
|
* too, after response has been started.
|
|
|
|
|
* future: have separate backend timeout, and then change this
|
|
|
|
|
* to check for write interest before checking for timeout */
|
|
|
|
|
/*if (waitevents & FDEVENT_OUT)*/
|
|
|
|
|
if ((con->state == CON_STATE_WRITE) &&
|
|
|
|
|
(con->write_request_ts != 0)) {
|
|
|
|
|
#if 0
|
|
|
|
|
if (srv->cur_ts - con->write_request_ts > 60) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sdd",
|
|
|
|
|
"connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
|
|
|
|
|
/* time - out */
|
|
|
|
|
if (con->conf.log_timeouts) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbsbsosds",
|
|
|
|
|
"NOTE: a request from",
|
|
|
|
|
con->dst_addr_buf,
|
|
|
|
|
"for",
|
|
|
|
|
con->request.uri,
|
|
|
|
|
"timed out after writing",
|
|
|
|
|
con->bytes_written,
|
|
|
|
|
"bytes. We waited",
|
|
|
|
|
(int)con->conf.max_write_idle,
|
|
|
|
|
"seconds. If this a problem increase server.max-write-idle");
|
|
|
|
|
}
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we don't like div by zero */
|
|
|
|
|
if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
|
|
|
|
|
|
|
|
|
|
if (con->traffic_limit_reached &&
|
|
|
|
|
(con->conf.kbytes_per_second == 0 ||
|
|
|
|
|
((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
|
|
|
|
|
/* enable connection again */
|
|
|
|
|
con->traffic_limit_reached = 0;
|
|
|
|
|
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
con->bytes_written_cur_second = 0;
|
|
|
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
|
connection_state_machine(srv, con);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (graceful_shutdown && !srv_shutdown) connection_graceful_shutdown_maint(srv);
|
|
|
|
|
connection_periodic_maint(srv, min_ts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__attribute_noinline__
|
|
|
|
|