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