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); }