]> granicus.if.org Git - apache/commitdiff
Allow the core_output_filter to save data in the filter past the end of
authorRyan Bloom <rbb@apache.org>
Sun, 5 Nov 2000 04:06:17 +0000 (04:06 +0000)
committerRyan Bloom <rbb@apache.org>
Sun, 5 Nov 2000 04:06:17 +0000 (04:06 +0000)
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
modules/http/http_request.c

index 8f29f01498041ba5b93bfbedb5d5c559f3c0c47d..5d518791ecbcc8c5876bbf81ce6fa0901500e5f0 100644 (file)
@@ -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;
         }
index 7ab2f76ce21b822fc0fbfd9cb89f1c421441a4e1..6ea6e6e75be05ed29cf48ed84ff31a6903db5e13 100644 (file)
@@ -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);
 }