From: Stefan Eissing Date: Sat, 25 Feb 2017 11:39:05 +0000 (+0000) Subject: On the trunk: X-Git-Tag: 2.5.0-alpha~607 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ba5f02060001052284ce61dc283f1972886d396e;p=apache On the trunk: mod_http2: signal eos on request input earlier, avoid unnecessary chunked, empty bodies, removing atomics from beam produce/consumed callback handling. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1784366 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 6ba8108449..25dc9711b5 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_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; }