File apache2-mod_http2-1.10.20.patch of Package apache2.27541
diff -upr modules/http2/h2_bucket_beam.c modules/http2/h2_bucket_beam.c
--- a/modules/http2/h2_bucket_beam.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_bucket_beam.c 2018-05-30 21:13:36.000000000 +0200
@@ -550,6 +550,7 @@ static void recv_buffer_cleanup(h2_bucke
apr_brigade_destroy(bb);
if (bl) enter_yellow(beam, bl);
+ apr_thread_cond_broadcast(beam->change);
if (beam->cons_ev_cb) {
beam->cons_ev_cb(beam->cons_ctx, beam);
}
@@ -707,12 +708,10 @@ void h2_beam_abort(h2_bucket_beam *beam)
h2_beam_lock bl;
if (beam && enter_yellow(beam, &bl) == APR_SUCCESS) {
- if (!beam->aborted) {
- beam->aborted = 1;
- r_purge_sent(beam);
- h2_blist_cleanup(&beam->send_list);
- report_consumption(beam, &bl);
- }
+ beam->aborted = 1;
+ r_purge_sent(beam);
+ h2_blist_cleanup(&beam->send_list);
+ report_consumption(beam, &bl);
apr_thread_cond_broadcast(beam->change);
leave_yellow(beam, &bl);
}
@@ -924,6 +923,7 @@ apr_status_t h2_beam_send(h2_bucket_beam
while (!APR_BRIGADE_EMPTY(sender_bb) && APR_SUCCESS == rv) {
if (space_left <= 0) {
report_prod_io(beam, force_report, &bl);
+ r_purge_sent(beam);
rv = wait_not_full(beam, block, &space_left, &bl);
if (APR_SUCCESS != rv) {
break;
diff -upr modules/http2/h2_config.c modules/http2/h2_config.c
--- a/modules/http2/h2_config.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_config.c 2018-05-29 23:06:49.000000000 +0200
@@ -604,6 +604,30 @@ static const char *h2_conf_set_early_hin
return "value must be On or Off";
}
+void h2_get_num_workers(server_rec *s, int *minw, int *maxw)
+{
+ int threads_per_child = 0;
+ const h2_config *config = h2_config_sget(s);
+
+ *minw = h2_config_geti(config, H2_CONF_MIN_WORKERS);
+ *maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS);
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child);
+
+ if (*minw <= 0) {
+ *minw = threads_per_child;
+ }
+ if (*maxw <= 0) {
+ /* As a default, this seems to work quite well under mpm_event.
+ * For people enabling http2 under mpm_prefork, start 4 threads unless
+ * configured otherwise. People get unhappy if their http2 requests are
+ * blocking each other. */
+ *maxw = 3 * (*minw) / 2;
+ if (*maxw < 4) {
+ *maxw = 4;
+ }
+ }
+}
+
#define AP_END_CMD AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
const command_rec h2_cmds[] = {
diff -upr modules/http2/h2_config.h modules/http2/h2_config.h
--- a/modules/http2/h2_config.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_config.h 2018-05-29 23:06:49.000000000 +0200
@@ -95,6 +95,8 @@ const h2_config *h2_config_rget(request_
int h2_config_geti(const h2_config *conf, h2_config_var_t var);
apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var);
+void h2_get_num_workers(server_rec *s, int *minw, int *maxw);
+
void h2_config_init(apr_pool_t *pool);
const struct h2_priority *h2_config_get_priority(const h2_config *conf,
diff -upr modules/http2/h2_conn.c modules/http2/h2_conn.c
--- a/modules/http2/h2_conn.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_conn.c 2018-05-30 21:13:36.000000000 +0200
@@ -127,18 +127,7 @@ apr_status_t h2_conn_child_init(apr_pool
h2_config_init(pool);
- minw = h2_config_geti(config, H2_CONF_MIN_WORKERS);
- maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS);
- if (minw <= 0) {
- minw = max_threads_per_child;
- }
- if (maxw <= 0) {
- /* As a default, this seems to work quite well under mpm_event.
- * For people enabling http2 under mpm_prefork, start 4 threads unless
- * configured otherwise. People get unhappy if their http2 requests are
- * blocking each other. */
- maxw = H2MAX(3 * minw / 2, 4);
- }
+ h2_get_num_workers(s, &minw, &maxw);
idle_secs = h2_config_geti(config, H2_CONF_MAX_WORKER_IDLE_SECS);
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
@@ -240,7 +229,19 @@ apr_status_t h2_conn_run(struct h2_ctx *
&& mpm_state != AP_MPMQ_STOPPING);
if (c->cs) {
- c->cs->state = CONN_STATE_LINGER;
+ switch (session->state) {
+ case H2_SESSION_ST_INIT:
+ case H2_SESSION_ST_IDLE:
+ case H2_SESSION_ST_BUSY:
+ case H2_SESSION_ST_WAIT:
+ c->cs->state = CONN_STATE_WRITE_COMPLETION;
+ break;
+ case H2_SESSION_ST_CLEANUP:
+ case H2_SESSION_ST_DONE:
+ default:
+ c->cs->state = CONN_STATE_LINGER;
+ break;
+ }
}
return APR_SUCCESS;
@@ -313,8 +314,6 @@ conn_rec *h2_slave_create(conn_rec *mast
c->log = NULL;
c->log_id = apr_psprintf(pool, "%ld-%d",
master->id, slave_id);
- /* Simulate that we had already a request on this connection. */
- c->keepalives = 1;
c->aborted = 0;
/* We cannot install the master connection socket on the slaves, as
* modules mess with timeouts/blocking of the socket, with
@@ -349,6 +348,14 @@ void h2_slave_destroy(conn_rec *slave)
apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd)
{
- return ap_run_pre_connection(slave, csd);
+ if (slave->keepalives == 0) {
+ /* Simulate that we had already a request on this connection. Some
+ * hooks trigger special behaviour when keepalives is 0.
+ * (Not necessarily in pre_connection, but later. Set it here, so it
+ * is in place.) */
+ slave->keepalives = 1;
+ return ap_run_pre_connection(slave, csd);
+ }
+ return APR_SUCCESS;
}
diff -upr modules/http2/h2_filter.c modules/http2/h2_filter.c
--- a/modules/http2/h2_filter.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_filter.c 2018-05-29 23:16:29.000000000 +0200
@@ -291,6 +291,8 @@ apr_bucket *h2_bucket_observer_beam(stru
}
static apr_status_t bbout(apr_bucket_brigade *bb, const char *fmt, ...)
+ __attribute__((format(printf,2,3)));
+static apr_status_t bbout(apr_bucket_brigade *bb, const char *fmt, ...)
{
va_list args;
apr_status_t rv;
@@ -351,8 +353,8 @@ static int add_stream(h2_stream *stream,
bbout(x->bb, " \"created\": %f,\n", ((double)stream->created)/APR_USEC_PER_SEC);
bbout(x->bb, " \"flowIn\": %d,\n", flowIn);
bbout(x->bb, " \"flowOut\": %d,\n", flowOut);
- bbout(x->bb, " \"dataIn\": %"APR_UINT64_T_FMT",\n", stream->in_data_octets);
- bbout(x->bb, " \"dataOut\": %"APR_UINT64_T_FMT"\n", stream->out_data_octets);
+ bbout(x->bb, " \"dataIn\": %"APR_OFF_T_FMT",\n", stream->in_data_octets);
+ bbout(x->bb, " \"dataOut\": %"APR_OFF_T_FMT"\n", stream->out_data_octets);
bbout(x->bb, " }");
++x->idx;
diff -upr modules/http2/h2_from_h1.c modules/http2/h2_from_h1.c
--- a/modules/http2/h2_from_h1.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_from_h1.c 2018-05-29 23:16:29.000000000 +0200
@@ -413,7 +413,7 @@ static apr_status_t pass_response(h2_tas
h2_headers *response = h2_headers_create(parser->http_status,
make_table(parser),
- NULL, task->pool);
+ NULL, 0, task->pool);
apr_brigade_cleanup(parser->tmp);
b = h2_bucket_headers_create(task->c->bucket_alloc, response);
APR_BRIGADE_INSERT_TAIL(parser->tmp, b);
@@ -772,6 +772,10 @@ apr_status_t h2_filter_request_in(ap_fil
APR_BUCKET_REMOVE(b);
apr_bucket_destroy(b);
ap_remove_input_filter(f);
+
+ if (headers->raw_bytes && h2_task_logio_add_bytes_in) {
+ h2_task_logio_add_bytes_in(task->c, headers->raw_bytes);
+ }
break;
}
}
diff -upr modules/http2/h2.h modules/http2/h2.h
--- a/modules/http2/h2.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2.h 2018-05-29 23:16:29.000000000 +0200
@@ -51,6 +51,9 @@ extern const char *H2_MAGIC_TOKEN;
/* Max data size to write so it fits inside a TLS record */
#define H2_DATA_CHUNK_SIZE ((16*1024) - 100 - 9)
+/* Size of the frame header itself in HTTP/2 */
+#define H2_FRAME_HDR_LEN 9
+
/* Maximum number of padding bytes in a frame, rfc7540 */
#define H2_MAX_PADLEN 256
/* Initial default window size, RFC 7540 ch. 6.5.2 */
@@ -137,6 +140,7 @@ struct h2_request {
apr_time_t request_time;
unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */
unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */
+ apr_off_t raw_bytes; /* RAW network bytes that generated this request - if known. */
};
typedef struct h2_headers h2_headers;
@@ -145,6 +149,7 @@ struct h2_headers {
int status;
apr_table_t *headers;
apr_table_t *notes;
+ apr_off_t raw_bytes; /* RAW network bytes that generated this request - if known. */
};
typedef apr_status_t h2_io_data_cb(void *ctx, const char *data, apr_off_t len);
diff -upr modules/http2/h2_h2.c modules/http2/h2_h2.c
--- a/modules/http2/h2_h2.c 2018-02-14 00:43:36.000000000 +0100
+++ b/modules/http2/h2_h2.c 2018-05-29 23:16:29.000000000 +0200
@@ -635,10 +635,10 @@ int h2_h2_process_conn(conn_rec* c)
}
h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
}
- else {
+ else if (APLOGctrace2(c)) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
- "h2_h2, not detected in %d bytes: %s",
- (int)slen, s);
+ "h2_h2, not detected in %d bytes(base64): %s",
+ (int)slen, h2_util_base64url_encode(s, slen, c->pool));
}
apr_brigade_destroy(temp);
diff -upr modules/http2/h2_headers.c modules/http2/h2_headers.c
--- a/modules/http2/h2_headers.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_headers.c 2018-05-29 23:16:29.000000000 +0200
@@ -111,7 +111,8 @@ apr_bucket *h2_bucket_headers_beam(struc
h2_headers *h2_headers_create(int status, apr_table_t *headers_in,
- apr_table_t *notes, apr_pool_t *pool)
+ apr_table_t *notes, apr_off_t raw_bytes,
+ apr_pool_t *pool)
{
h2_headers *headers = apr_pcalloc(pool, sizeof(h2_headers));
headers->status = status;
@@ -125,7 +126,7 @@ h2_headers *h2_headers_create(int status
h2_headers *h2_headers_rcreate(request_rec *r, int status,
apr_table_t *header, apr_pool_t *pool)
{
- h2_headers *headers = h2_headers_create(status, header, r->notes, pool);
+ h2_headers *headers = h2_headers_create(status, header, r->notes, 0, pool);
if (headers->status == HTTP_FORBIDDEN) {
const char *cause = apr_table_get(r->notes, "ssl-renegotiate-forbidden");
if (cause) {
@@ -149,7 +150,7 @@ h2_headers *h2_headers_rcreate(request_r
h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h)
{
return h2_headers_create(h->status, apr_table_copy(pool, h->headers),
- apr_table_copy(pool, h->notes), pool);
+ apr_table_copy(pool, h->notes), h->raw_bytes, pool);
}
h2_headers *h2_headers_die(apr_status_t type,
diff -upr modules/http2/h2_headers.h modules/http2/h2_headers.h
--- a/modules/http2/h2_headers.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_headers.h 2018-05-29 23:16:29.000000000 +0200
@@ -41,10 +41,12 @@ apr_bucket *h2_bucket_headers_beam(struc
* @param status the headers status
* @param header the headers of the headers
* @param notes the notes carried by the headers
+ * @param raw_bytes the raw network bytes (if known) used to transmit these
* @param pool the memory pool to use
*/
h2_headers *h2_headers_create(int status, apr_table_t *header,
- apr_table_t *notes, apr_pool_t *pool);
+ apr_table_t *notes, apr_off_t raw_bytes,
+ apr_pool_t *pool);
/**
* Create the headers from the given request_rec.
diff -upr modules/http2/h2_mplx.c modules/http2/h2_mplx.c
--- a/modules/http2/h2_mplx.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_mplx.c 2018-05-29 23:16:29.000000000 +0200
@@ -286,34 +286,6 @@ static int output_consumed_signal(h2_mpl
return 0;
}
-static void task_destroy(h2_mplx *m, h2_task *task)
-{
- conn_rec *slave = NULL;
- int reuse_slave = 0;
-
- slave = task->c;
-
- if (m->s->keep_alive_max == 0 || slave->keepalives < m->s->keep_alive_max) {
- reuse_slave = ((m->spare_slaves->nelts < (m->limit_active * 3 / 2))
- && !task->rst_error);
- }
-
- if (slave) {
- if (reuse_slave && slave->keepalive == AP_CONN_KEEPALIVE) {
- h2_beam_log(task->output.beam, m->c, APLOG_DEBUG,
- APLOGNO(03385) "h2_task_destroy, reuse slave");
- h2_task_destroy(task);
- APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave;
- }
- else {
- h2_beam_log(task->output.beam, m->c, APLOG_TRACE1,
- "h2_task_destroy, destroy slave");
- slave->sbh = NULL;
- h2_slave_destroy(slave);
- }
- }
-}
-
static int stream_destroy_iter(void *ctx, void *val)
{
h2_mplx *m = ctx;
@@ -331,8 +303,42 @@ static int stream_destroy_iter(void *ctx
}
if (stream->task) {
- task_destroy(m, stream->task);
+ h2_task *task = stream->task;
+ conn_rec *slave;
+ int reuse_slave = 0;
+
stream->task = NULL;
+ slave = task->c;
+ if (slave) {
+ /* On non-serialized requests, the IO logging has not accounted for any
+ * meta data send over the network: response headers and h2 frame headers. we
+ * counted this on the stream and need to add this now.
+ * This is supposed to happen before the EOR bucket triggers the
+ * logging of the transaction. *fingers crossed* */
+ if (task->request && !task->request->serialize && h2_task_logio_add_bytes_out) {
+ apr_off_t unaccounted = stream->out_frame_octets - stream->out_data_octets;
+ if (unaccounted > 0) {
+ h2_task_logio_add_bytes_out(slave, unaccounted);
+ }
+ }
+
+ if (m->s->keep_alive_max == 0 || slave->keepalives < m->s->keep_alive_max) {
+ reuse_slave = ((m->spare_slaves->nelts < (m->limit_active * 3 / 2))
+ && !task->rst_error);
+ }
+
+ if (reuse_slave && slave->keepalive == AP_CONN_KEEPALIVE) {
+ h2_beam_log(task->output.beam, m->c, APLOG_DEBUG,
+ APLOGNO(03385) "h2_task_destroy, reuse slave");
+ h2_task_destroy(task);
+ APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave;
+ }
+ else {
+ h2_beam_log(task->output.beam, m->c, APLOG_TRACE1,
+ "h2_task_destroy, destroy slave");
+ h2_slave_destroy(slave);
+ }
+ }
}
h2_stream_destroy(stream);
return 0;
diff -upr modules/http2/h2_proxy_util.c modules/http2/h2_proxy_util.c
--- a/modules/http2/h2_proxy_util.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_proxy_util.c 2018-06-14 23:44:06.000000000 +0200
@@ -916,8 +916,8 @@ static size_t subst_str(link_ctx *ctx, i
delta = nlen - olen;
plen = ctx->slen + delta + 1;
p = apr_pcalloc(ctx->pool, plen);
- strncpy(p, ctx->s, start);
- strncpy(p + start, ns, nlen);
+ memcpy(p, ctx->s, start);
+ memcpy(p + start, ns, nlen);
strcpy(p + start + nlen, ctx->s + end);
ctx->s = p;
ctx->slen = (int)strlen(p);
@@ -943,7 +943,7 @@ static void map_link(link_ctx *ctx)
/* common to use relative uris in link header, for mappings
* to work need to prefix the backend server uri */
need_len += ctx->psu_len;
- strncpy(buffer, ctx->p_server_uri, sizeof(buffer));
+ apr_cpystrn(buffer, ctx->p_server_uri, sizeof(buffer));
buffer_len = ctx->psu_len;
}
if (need_len > sizeof(buffer)) {
@@ -951,9 +951,7 @@ static void map_link(link_ctx *ctx)
"link_reverse_map uri too long, skipped: %s", ctx->s);
return;
}
- strncpy(buffer + buffer_len, ctx->s + ctx->link_start, link_len);
- buffer_len += link_len;
- buffer[buffer_len] = '\0';
+ apr_cpystrn(buffer + buffer_len, ctx->s + ctx->link_start, link_len + 1);
if (!prepend_p_server
&& strcmp(ctx->real_backend_uri, ctx->p_server_uri)
&& !strncmp(buffer, ctx->real_backend_uri, ctx->rbu_len)) {
@@ -961,8 +959,8 @@ static void map_link(link_ctx *ctx)
* to work, we need to use the proxy uri */
int path_start = ctx->link_start + ctx->rbu_len;
link_len -= ctx->rbu_len;
- strcpy(buffer, ctx->p_server_uri);
- strncpy(buffer + ctx->psu_len, ctx->s + path_start, link_len);
+ memcpy(buffer, ctx->p_server_uri, ctx->psu_len);
+ memcpy(buffer + ctx->psu_len, ctx->s + path_start, link_len);
buffer_len = ctx->psu_len + link_len;
buffer[buffer_len] = '\0';
}
diff -upr modules/http2/h2_push.c modules/http2/h2_push.c
--- a/modules/http2/h2_push.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_push.c 2018-05-29 23:16:29.000000000 +0200
@@ -352,7 +352,7 @@ static int add_push(link_ctx *ctx)
ctx->req->authority, path, headers,
ctx->req->serialize);
/* atm, we do not push on pushes */
- h2_request_end_headers(req, ctx->pool, 1);
+ h2_request_end_headers(req, ctx->pool, 1, 0);
push->req = req;
if (has_param(ctx, "critical")) {
h2_priority *prio = apr_pcalloc(ctx->pool, sizeof(*prio));
diff -upr modules/http2/h2_request.c modules/http2/h2_request.c
--- a/modules/http2/h2_request.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_request.c 2018-05-29 23:16:29.000000000 +0200
@@ -150,7 +150,7 @@ apr_status_t h2_request_add_header(h2_re
return status;
}
-apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos)
+apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos, size_t raw_bytes)
{
const char *s;
@@ -190,7 +190,8 @@ apr_status_t h2_request_end_headers(h2_r
apr_table_setn(req->headers, "Content-Length", "0");
}
}
-
+ req->raw_bytes += raw_bytes;
+
return APR_SUCCESS;
}
diff -upr modules/http2/h2_request.h modules/http2/h2_request.h
--- a/modules/http2/h2_request.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_request.h 2018-05-29 23:16:29.000000000 +0200
@@ -30,7 +30,7 @@ apr_status_t h2_request_add_trailer(h2_r
const char *name, size_t nlen,
const char *value, size_t vlen);
-apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos);
+apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos, size_t raw_bytes);
h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src);
diff -upr modules/http2/h2_session.c modules/http2/h2_session.c
--- a/modules/http2/h2_session.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_session.c 2018-05-29 23:16:29.000000000 +0200
@@ -348,7 +348,8 @@ static int on_frame_recv_cb(nghttp2_sess
* trailers */
stream = h2_session_stream_get(session, frame->hd.stream_id);
if (stream) {
- rv = h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags);
+ rv = h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags,
+ frame->hd.length + H2_FRAME_HDR_LEN);
}
break;
case NGHTTP2_DATA:
@@ -358,7 +359,8 @@ static int on_frame_recv_cb(nghttp2_sess
H2_STRM_LOG(APLOGNO(02923), stream,
"DATA, len=%ld, flags=%d"),
(long)frame->hd.length, frame->hd.flags);
- rv = h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags);
+ rv = h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags,
+ frame->hd.length + H2_FRAME_HDR_LEN);
}
break;
case NGHTTP2_PRIORITY:
@@ -546,7 +548,8 @@ static int on_frame_send_cb(nghttp2_sess
stream = h2_session_stream_get(session, stream_id);
if (stream) {
- h2_stream_send_frame(stream, frame->hd.type, frame->hd.flags);
+ h2_stream_send_frame(stream, frame->hd.type, frame->hd.flags,
+ frame->hd.length + H2_FRAME_HDR_LEN);
}
return 0;
}
diff -upr modules/http2/h2_stream.c modules/http2/h2_stream.c
--- a/modules/http2/h2_stream.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_stream.c 2018-05-29 23:16:29.000000000 +0200
@@ -221,7 +221,8 @@ static apr_status_t close_input(h2_strea
stream->in_buffer = apr_brigade_create(stream->pool, c->bucket_alloc);
}
- r = h2_headers_create(HTTP_OK, stream->trailers, NULL, stream->pool);
+ r = h2_headers_create(HTTP_OK, stream->trailers, NULL,
+ stream->in_trailer_octets, stream->pool);
stream->trailers = NULL;
b = h2_bucket_headers_create(c->bucket_alloc, r);
APR_BRIGADE_INSERT_TAIL(stream->in_buffer, b);
@@ -369,7 +370,7 @@ static void set_policy_for(h2_stream *st
r->serialize = h2_config_geti(stream->session->config, H2_CONF_SER_HEADERS);
}
-apr_status_t h2_stream_send_frame(h2_stream *stream, int ftype, int flags)
+apr_status_t h2_stream_send_frame(h2_stream *stream, int ftype, int flags, size_t frame_len)
{
apr_status_t status = APR_SUCCESS;
int new_state, eos = 0;
@@ -381,7 +382,9 @@ apr_status_t h2_stream_send_frame(h2_str
AP_DEBUG_ASSERT(new_state > S_XXX);
return transit(stream, new_state);
}
-
+
+ ++stream->out_frames;
+ stream->out_frame_octets += frame_len;
switch (ftype) {
case NGHTTP2_DATA:
eos = (flags & NGHTTP2_FLAG_END_STREAM);
@@ -395,7 +398,7 @@ apr_status_t h2_stream_send_frame(h2_str
/* start pushed stream */
ap_assert(stream->request == NULL);
ap_assert(stream->rtmp != NULL);
- status = h2_request_end_headers(stream->rtmp, stream->pool, 1);
+ status = h2_request_end_headers(stream->rtmp, stream->pool, 1, 0);
if (status != APR_SUCCESS) {
return status;
}
@@ -416,7 +419,7 @@ apr_status_t h2_stream_send_frame(h2_str
return status;
}
-apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags)
+apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags, size_t frame_len)
{
apr_status_t status = APR_SUCCESS;
int new_state, eos = 0;
@@ -441,6 +444,7 @@ apr_status_t h2_stream_recv_frame(h2_str
if (!eos) {
h2_stream_rst(stream, H2_ERR_PROTOCOL_ERROR);
}
+ stream->in_trailer_octets += frame_len;
}
else {
/* request HEADER */
@@ -452,7 +456,7 @@ apr_status_t h2_stream_recv_frame(h2_str
* to abort the connection here, since this is clearly a protocol error */
return APR_EINVAL;
}
- status = h2_request_end_headers(stream->rtmp, stream->pool, eos);
+ status = h2_request_end_headers(stream->rtmp, stream->pool, eos, frame_len);
if (status != APR_SUCCESS) {
return status;
}
@@ -629,7 +633,7 @@ apr_status_t h2_stream_set_request_rec(h
stream->rtmp = req;
/* simulate the frames that led to this */
return h2_stream_recv_frame(stream, NGHTTP2_HEADERS,
- NGHTTP2_FLAG_END_STREAM);
+ NGHTTP2_FLAG_END_STREAM, 0);
}
return status;
}
diff -upr modules/http2/h2_stream.h modules/http2/h2_stream.h
--- a/modules/http2/h2_stream.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_stream.h 2018-05-29 23:16:29.000000000 +0200
@@ -96,10 +96,13 @@ struct h2_stream {
struct h2_task *task; /* assigned task to fullfill request */
const h2_priority *pref_priority; /* preferred priority for this stream */
+ apr_off_t out_frames; /* # of frames sent out */
+ apr_off_t out_frame_octets; /* # of RAW frame octets sent out */
apr_off_t out_data_frames; /* # of DATA frames sent */
apr_off_t out_data_octets; /* # of DATA octets (payload) sent */
apr_off_t in_data_frames; /* # of DATA frames received */
apr_off_t in_data_octets; /* # of DATA octets (payload) received */
+ apr_off_t in_trailer_octets; /* # of HEADER octets (payload) received in trailers */
h2_stream_monitor *monitor; /* optional monitor for stream states */
};
@@ -196,8 +199,8 @@ apr_status_t h2_stream_add_header(h2_str
const char *name, size_t nlen,
const char *value, size_t vlen);
-apr_status_t h2_stream_send_frame(h2_stream *stream, int frame_type, int flags);
-apr_status_t h2_stream_recv_frame(h2_stream *stream, int frame_type, int flags);
+apr_status_t h2_stream_send_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len);
+apr_status_t h2_stream_recv_frame(h2_stream *stream, int frame_type, int flags, size_t frame_len);
/*
* Process a frame of received DATA.
diff -upr modules/http2/h2_task.c modules/http2/h2_task.c
--- a/modules/http2/h2_task.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_task.c 2018-05-29 23:16:29.000000000 +0200
@@ -675,7 +675,14 @@ static apr_status_t h2_task_process_requ
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
"h2_task(%s): start process_request", task->id);
+ /* Add the raw bytes of the request (e.g. header frame lengths to
+ * the logio for this request. */
+ if (req->raw_bytes && h2_task_logio_add_bytes_in) {
+ h2_task_logio_add_bytes_in(c, req->raw_bytes);
+ }
+
ap_process_request(r);
+
if (task->frozen) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
"h2_task(%s): process_request frozen", task->id);
diff -upr modules/http2/h2_version.h modules/http2/h2_version.h
--- a/modules/http2/h2_version.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/h2_version.h 2018-05-30 21:13:36.000000000 +0200
@@ -27,7 +27,7 @@
* @macro
* Version number of the http2 module as c string
*/
-#define MOD_HTTP2_VERSION "1.10.16"
+#define MOD_HTTP2_VERSION "1.10.20"
/**
* @macro
@@ -35,7 +35,7 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_HTTP2_VERSION_NUM 0x010a10
+#define MOD_HTTP2_VERSION_NUM 0x010a14
#endif /* mod_h2_h2_version_h */
diff -upr modules/http2/mod_http2.c modules/http2/mod_http2.c
--- a/modules/http2/mod_http2.c 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/mod_http2.c 2018-05-29 23:06:49.000000000 +0200
@@ -193,6 +193,11 @@ static void http2_req_engine_done(h2_req
h2_mplx_req_engine_done(ngn, r_conn, status);
}
+static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
+{
+ h2_get_num_workers(s, minw, maxw);
+}
+
/* Runs once per created child process. Perform any process
* related initionalization here.
*/
@@ -218,6 +223,7 @@ static void h2_hooks(apr_pool_t *pool)
APR_REGISTER_OPTIONAL_FN(http2_req_engine_push);
APR_REGISTER_OPTIONAL_FN(http2_req_engine_pull);
APR_REGISTER_OPTIONAL_FN(http2_req_engine_done);
+ APR_REGISTER_OPTIONAL_FN(http2_get_num_workers);
ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
diff -upr modules/http2/mod_http2.h modules/http2/mod_http2.h
--- a/modules/http2/mod_http2.h 2018-02-10 16:46:12.000000000 +0100
+++ b/modules/http2/mod_http2.h 2018-05-29 23:06:49.000000000 +0200
@@ -93,4 +93,9 @@ APR_DECLARE_OPTIONAL_FN(void,
http2_req_engine_done, (h2_req_engine *engine,
conn_rec *rconn,
apr_status_t status));
+
+APR_DECLARE_OPTIONAL_FN(void,
+ http2_get_num_workers, (server_rec *s,
+ int *minw, int *max));
+
#endif