From 77e5b33c2eb4d65d2098794f270e8b794e2ccca0 Mon Sep 17 00:00:00 2001 From: Ryan Bloom Date: Sun, 5 Nov 2000 04:06:17 +0000 Subject: [PATCH] Allow the core_output_filter to save data in the filter past the end of the first request if this is a keepalive connection. This allows us to save the end of the first request until we have enough data from the second request to make it worthwhile to send the responses. In order to do this, we need to allocate mmap's from the connection pool instead of the request pool. If we don't use the connection pool, then the mmap is freed before the data is sent, because the mmap is freed at the end of the first request. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@86840 13f79535-47bb-0310-9956-ffa450edef68 --- modules/http/http_core.c | 13 +++++++++++-- modules/http/http_request.c | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 8f29f01498..5d518791ec 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -2979,7 +2979,7 @@ static int default_handler(request_rec *r) /* we need to protect ourselves in case we die while we've got the * file mmapped */ apr_status_t status; - if ((status = apr_mmap_create(&mm, fd, 0, r->finfo.size, r->pool)) != APR_SUCCESS) { + if ((status = apr_mmap_create(&mm, fd, 0, r->finfo.size, r->connection->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, "default_handler: mmap failed: %s", r->filename); mm = NULL; @@ -3414,7 +3414,16 @@ static apr_status_t core_output_filter(ap_filter_t *f, ap_bucket_brigade *b) /* Completed iterating over the brigades, now determine if we want to * buffer the brigade or send the brigade out on the network */ - if (!fd && (!more) && (nbytes < MIN_SIZE_TO_WRITE) && !AP_BUCKET_IS_EOS(e) && !AP_BUCKET_IS_FLUSH(e)) { + if (!fd && (!more) && (nbytes < MIN_SIZE_TO_WRITE) && !AP_BUCKET_IS_FLUSH(e) || (AP_BUCKET_IS_EOS(e) && c->keepalive)) { + + /* NEVER save an EOS in here. If we are saving a brigade with an + * EOS bucket, then we are doing keepalive connections, and we want + * to process to second request fully. + */ + if (AP_BUCKET_IS_EOS(e)) { + AP_BUCKET_REMOVE(e); + ap_bucket_destroy(e); + } ap_save_brigade(f, &ctx->b, &b); return APR_SUCCESS; } diff --git a/modules/http/http_request.c b/modules/http/http_request.c index 7ab2f76ce2..6ea6e6e75b 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -1367,6 +1367,22 @@ static void process_request_internal(request_rec *r) ap_finalize_request_protocol(r); } +static void check_pipeline_flush(request_rec *r) +{ + ap_bucket_brigade *bb = ap_brigade_create(r->pool); + if (ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK) != APR_SUCCESS) { + ap_bucket *e = ap_bucket_create_flush(); + + /* We just send directly to the connection based filters, because at + * this point, we know that we have seen all of the data, so we just + * want to flush the buckets if something hasn't been sent to the + * network yet. + */ + AP_BRIGADE_INSERT_HEAD(bb, e); + ap_pass_brigade(r->connection->output_filters, bb); + } +} + void ap_process_request(request_rec *r) { process_request_internal(r); @@ -1378,7 +1394,7 @@ void ap_process_request(request_rec *r) * this packet, then it'll appear like the link is stalled when really * it's the application that's stalled. */ - ap_bhalfduplex(r->connection->client); + check_pipeline_flush(r); ap_run_log_transaction(r); } -- 2.50.1