diff options
author | Stefan Eissing <icing@apache.org> | 2021-07-06 15:06:00 +0200 |
---|---|---|
committer | Stefan Eissing <icing@apache.org> | 2021-07-06 15:06:00 +0200 |
commit | 2d3427861273955103112c68ed8496d6fa94ad0b (patch) | |
tree | 4346848b0b6916f724ca4eea382d801d31916fdb /modules/http2/h2_mplx.c | |
parent | Trigger ci. (diff) | |
download | apache2-2d3427861273955103112c68ed8496d6fa94ad0b.tar.xz apache2-2d3427861273955103112c68ed8496d6fa94ad0b.zip |
*) mod_http2:
- Aborting requests via RST_STREAM no longer affect the available
resources of a connection when the first chunk of the response
body has been sent.
- H2Min/MaxWorkers behave as intended again. The module will initially
create H2MinWorkers threads and add up to H2MaxWorkers when needed. These
additional workers time out when idle after H2MaxWorkerIdleSeconds and
disappear again.
- When the shutdown of a child is detected (e.g. graceful shutdown), the
module will terminate all idle workers above H2MinWorkers right away.
This detection currently only happens when a HTTP/2 connection is active.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1891312 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http2/h2_mplx.c')
-rw-r--r-- | modules/http2/h2_mplx.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c index d787e0d09d..7ab5ec9300 100644 --- a/modules/http2/h2_mplx.c +++ b/modules/http2/h2_mplx.c @@ -739,6 +739,12 @@ static h2_task *s_next_stream_task(h2_mplx *m) return stream->task; } } + if (m->tasks_active >= m->limit_active && !h2_iq_empty(m->q)) { + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, + "h2_session(%ld): delaying request processing. " + "Current limit is %d and %d workers are in use.", + m->id, m->limit_active, m->tasks_active); + } return NULL; } @@ -1132,14 +1138,36 @@ int h2_mplx_m_awaits_data(h2_mplx *m) return waiting; } +static int reset_is_acceptable(h2_stream *stream) +{ + /* client may terminate a stream via H2 RST_STREAM message at any time. + * This is annyoing when we have committed resources (e.g. worker threads) + * to it, so our mood (e.g. willingness to commit resources on this + * connection in the future) goes down. + * + * This is a DoS protection. We do not want to make it too easy for + * a client to eat up server resources. + * + * However: there are cases where a RST_STREAM is the only way to end + * a request. This includes websockets and server-side-event streams (SSEs). + * The responses to such requests continue forever otherwise. + * + */ + if (!stream->task) return 1; /* have not started or already ended for us. acceptable. */ + if (!(stream->id & 0x01)) return 1; /* stream initiated by us. acceptable. */ + if (!stream->has_response) return 0; /* no response headers produced yet. bad. */ + if (!stream->out_data_frames) return 0; /* no response body data sent yet. bad. */ + return 1; /* otherwise, be forgiving */ +} + apr_status_t h2_mplx_m_client_rst(h2_mplx *m, int stream_id) { h2_stream *stream; apr_status_t status = APR_SUCCESS; - + H2_MPLX_ENTER_ALWAYS(m); stream = h2_ihash_get(m->streams, stream_id); - if (stream && stream->task) { + if (stream && !reset_is_acceptable(stream)) { status = m_be_annoyed(m); } H2_MPLX_LEAVE(m); |