From: Stefan Eissing Date: Sat, 25 Feb 2017 12:30:28 +0000 (+0000) Subject: On the 2.4.x branch: X-Git-Tag: 2.4.26~284 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60e2abd302b55ab250479d24653cd0ab90649990;p=apache On the 2.4.x branch: Merged /httpd/httpd/trunk:r1784002,1784366,1784372 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1784374 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/http2/h2_bucket_beam.c b/modules/http2/h2_bucket_beam.c index f45fa470a4..3d644fd68e 100644 --- a/modules/http2/h2_bucket_beam.c +++ b/modules/http2/h2_bucket_beam.c @@ -230,15 +230,12 @@ static apr_off_t bucket_mem_used(apr_bucket *b) static int report_consumption(h2_bucket_beam *beam) { int rv = 0; - if (apr_atomic_read32(&beam->cons_ev_pending)) { - if (beam->cons_io_cb) { - beam->cons_io_cb(beam->cons_ctx, beam, beam->received_bytes - - beam->cons_bytes_reported); - rv = 1; - } - beam->cons_bytes_reported = beam->received_bytes; - apr_atomic_set32(&beam->cons_ev_pending, 0); + if (beam->cons_io_cb) { + beam->cons_io_cb(beam->cons_ctx, beam, beam->received_bytes + - beam->cons_bytes_reported); + rv = 1; } + beam->cons_bytes_reported = beam->received_bytes; return rv; } @@ -1024,7 +1021,6 @@ transfer: } if (transferred_buckets > 0) { - apr_atomic_set32(&beam->cons_ev_pending, 1); if (beam->cons_ev_cb) { beam->cons_ev_cb(beam->cons_ctx, beam); } @@ -1199,15 +1195,13 @@ int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file) int h2_beam_report_consumption(h2_bucket_beam *beam) { - if (apr_atomic_read32(&beam->cons_ev_pending)) { - h2_beam_lock bl; - if (enter_yellow(beam, &bl) == APR_SUCCESS) { - int rv = report_consumption(beam); - leave_yellow(beam, &bl); - return rv; - } + h2_beam_lock bl; + int rv = 0; + if (enter_yellow(beam, &bl) == APR_SUCCESS) { + rv = report_consumption(beam); + leave_yellow(beam, &bl); } - return 0; + return rv; } void h2_beam_log(h2_bucket_beam *beam, conn_rec *c, int level, const char *msg) diff --git a/modules/http2/h2_bucket_beam.h b/modules/http2/h2_bucket_beam.h index f5fe7755a6..2b54eee8b0 100644 --- a/modules/http2/h2_bucket_beam.h +++ b/modules/http2/h2_bucket_beam.h @@ -194,13 +194,11 @@ struct h2_bucket_beam { h2_beam_mutex_enter *m_enter; struct apr_thread_cond_t *m_cond; - apr_uint32_t cons_ev_pending; /* != 0, consumer event pending */ apr_off_t cons_bytes_reported; /* amount of bytes reported as consumed */ h2_beam_ev_callback *cons_ev_cb; h2_beam_io_callback *cons_io_cb; void *cons_ctx; - apr_uint32_t prod_ev_pending; /* != 0, producer event pending */ apr_off_t prod_bytes_reported; /* amount of bytes reported as produced */ h2_beam_io_callback *prod_io_cb; void *prod_ctx; diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c index bbf8d596af..465eb9bb4f 100644 --- a/modules/http2/h2_mplx.c +++ b/modules/http2/h2_mplx.c @@ -123,7 +123,8 @@ static apr_status_t beam_enter(void *ctx, h2_beam_lock *pbl) static void stream_output_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length) { - h2_task *task = ctx; + h2_stream *stream = ctx; + h2_task *task = stream->task; if (length > 0 && task && task->assigned) { h2_req_engine_out_consumed(task->assigned, task->c, length); } @@ -613,7 +614,7 @@ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam) "h2_mplx(%s): out open", stream->task->id); } - h2_beam_on_consumed(stream->output, NULL, stream_output_consumed, stream->task); + h2_beam_on_consumed(stream->output, NULL, stream_output_consumed, stream); h2_beam_on_produced(stream->output, output_produced, m); beamed_count = h2_beam_get_files_beamed(stream->output); if (m->tx_handles_reserved >= beamed_count) { diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c index b6f13c4734..7faf39340c 100644 --- a/modules/http2/h2_request.c +++ b/modules/http2/h2_request.c @@ -170,7 +170,10 @@ apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos) s = apr_table_get(req->headers, "Content-Length"); if (!s) { - /* no content-length given */ + /* HTTP/2 does not need a Content-Length for framing, but our + * internal request processing is used to HTTP/1.1, so we + * need to either add a Content-Length or a Transfer-Encoding + * if any content can be expected. */ if (!eos) { /* We have not seen a content-length and have no eos, * simulate a chunked encoding for our HTTP/1.1 infrastructure, diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c index d5ac7662ab..99a9c094d7 100644 --- a/modules/http2/h2_session.c +++ b/modules/http2/h2_session.c @@ -27,6 +27,8 @@ #include #include +#include + #include "h2_private.h" #include "h2.h" #include "h2_bucket_eos.h" @@ -711,16 +713,31 @@ static h2_session *h2_session_create_int(conn_rec *c, { nghttp2_session_callbacks *callbacks = NULL; nghttp2_option *options = NULL; + apr_allocator_t *allocator; + apr_thread_mutex_t *mutex; uint32_t n; - apr_pool_t *pool = NULL; - apr_status_t status = apr_pool_create(&pool, c->pool); h2_session *session; + + apr_status_t status = apr_allocator_create(&allocator); if (status != APR_SUCCESS) { return NULL; } + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&pool, c->pool, NULL, allocator); + if (!pool) { + apr_allocator_destroy(allocator); + return NULL; + } apr_pool_tag(pool, "h2_session"); - + apr_allocator_owner_set(allocator, pool); + status = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, pool); + if (status != APR_SUCCESS) { + apr_pool_destroy(pool); + return NULL; + } + apr_allocator_mutex_set(allocator, mutex); + /* get h2_session a lifetime beyond its pool and everything * connected to it. */ session = apr_pcalloc(pool, sizeof(h2_session)); diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c index 0a893525ee..c4b1227d6a 100644 --- a/modules/http2/h2_stream.c +++ b/modules/http2/h2_stream.c @@ -361,7 +361,7 @@ apr_status_t h2_stream_send_frame(h2_stream *stream, int ftype, int flags) /* start pushed stream */ ap_assert(stream->request == NULL); ap_assert(stream->rtmp != NULL); - status = h2_request_end_headers(stream->rtmp, stream->pool, 0); + status = h2_request_end_headers(stream->rtmp, stream->pool, 1); if (status != APR_SUCCESS) { return status; } @@ -412,7 +412,7 @@ apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags) /* request HEADER */ ap_assert(stream->request == NULL); ap_assert(stream->rtmp != NULL); - status = h2_request_end_headers(stream->rtmp, stream->pool, 0); + status = h2_request_end_headers(stream->rtmp, stream->pool, eos); if (status != APR_SUCCESS) { return status; } diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h index dee64a3085..0d7508ba01 100644 --- a/modules/http2/h2_version.h +++ b/modules/http2/h2_version.h @@ -26,7 +26,7 @@ * @macro * Version number of the http2 module as c string */ -#define MOD_HTTP2_VERSION "1.9.1" +#define MOD_HTTP2_VERSION "1.9.2" /** * @macro @@ -34,7 +34,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 0x010901 +#define MOD_HTTP2_VERSION_NUM 0x010902 #endif /* mod_h2_h2_version_h */