]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
core: core output filter to cleanup empty/meta buckets following data, ASAP.
authorYann Ylavic <ylavic@apache.org>
Thu, 19 Aug 2021 16:04:45 +0000 (16:04 +0000)
committerYann Ylavic <ylavic@apache.org>
Thu, 19 Aug 2021 16:04:45 +0000 (16:04 +0000)
* server/core_filters.c (delete_meta_bucket):
  Add delete_meta_bucket() helper to set r->flush on EOR.

* server/core_filters.c (send_brigade_nonblocking):
  Use delete_meta_bucket() to factorize code.

* server/core_filters.c (writev_nonblocking):
  Use delete_meta_bucket() to factorize code.
  Cleanup trailing empty/meta buckets immediately after data have been sent to
  get more accurate EOR timestamp (otherwise trailing buckets could be deleted
  only after the next data or with a final send_brigade_nonblocking() call in
  the output filter).

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1892452 13f79535-47bb-0310-9956-ffa450edef68

server/core_filters.c

index 0325dea452d51d22f234a96d2ce355ab4c101d2a..5868539ec87b41a4fdc02db5e864062edf45cc56 100644 (file)
@@ -480,6 +480,19 @@ static APR_INLINE int can_sendfile_bucket(apr_bucket *b)
 }
 #endif
 
+static void delete_meta_bucket(apr_bucket *bucket)
+{
+    if (AP_BUCKET_IS_EOR(bucket)) {
+        /* Mark the request as flushed since all its
+         * buckets (preceding this EOR) have been sent.
+         */
+        request_rec *r = ap_bucket_eor_request(bucket);
+        ap_assert(r != NULL);
+        r->flushed = 1;
+    }
+    apr_bucket_delete(bucket);
+}
+
 static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
                                              apr_bucket_brigade *bb,
                                              core_output_ctx_t *ctx,
@@ -551,15 +564,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
              * brigade in order.
              */
             if (!nvec) {
-                if (AP_BUCKET_IS_EOR(bucket)) {
-                    /* Mark the request as flushed since all its
-                     * buckets (preceding this EOR) have been sent.
-                     */
-                    request_rec *r = ap_bucket_eor_request(bucket);
-                    ap_assert(r != NULL);
-                    r->flushed = 1;
-                }
-                apr_bucket_delete(bucket);
+                delete_meta_bucket(bucket);
             }
             continue;
         }
@@ -643,15 +648,7 @@ static apr_status_t writev_nonblocking(apr_socket_t *s,
         for (i = offset; i < nvec; ) {
             apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
             if (!bucket->length) {
-                if (AP_BUCKET_IS_EOR(bucket)) {
-                    /* Mark the request as flushed since all its
-                     * buckets (preceding this EOR) have been sent.
-                     */
-                    request_rec *r = ap_bucket_eor_request(bucket);
-                    ap_assert(r != NULL);
-                    r->flushed = 1;
-                }
-                apr_bucket_delete(bucket);
+                delete_meta_bucket(bucket);
             }
             else if (n >= vec[i].iov_len) {
                 apr_bucket_delete(bucket);
@@ -668,6 +665,16 @@ static apr_status_t writev_nonblocking(apr_socket_t *s,
                 break;
             }
         }
+        if (i == nvec) {
+            /* Cleanup empty/meta buckets following sent data */
+            while (!APR_BRIGADE_EMPTY(bb)) {
+                apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
+                if (bucket->length) {
+                    break;
+                }
+                delete_meta_bucket(bucket);
+            }
+        }
     } while (rv == APR_SUCCESS && bytes_written < bytes_to_write);
 
     if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {