]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_http2: H2HEADER buckets have the correct lenght of zero and no
authorStefan Eissing <icing@apache.org>
Thu, 14 Oct 2021 09:58:37 +0000 (09:58 +0000)
committerStefan Eissing <icing@apache.org>
Thu, 14 Oct 2021 09:58:37 +0000 (09:58 +0000)
     longer smuggle the contained field lengths in this field. Instead
     the bytes reportded to mod_logio are counted specifically.

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

modules/http2/h2.h
modules/http2/h2_bucket_beam.c
modules/http2/h2_c2.c
modules/http2/h2_headers.c
modules/http2/h2_headers.h
test/modules/http2/test_400_push.py

index 59d6a46d8e571173c96e9f3feb98bd0f9ad4b859..860487d7b5e637faff3a691a5b0d9b0444dc5742 100644 (file)
@@ -152,7 +152,7 @@ struct h2_request {
     apr_table_t *headers;
 
     apr_time_t request_time;
-    int chunked;                /* iff request body needs to be forwarded as chunked */
+    unsigned int chunked : 1;   /* iff request body needs to be forwarded as chunked */
     apr_off_t raw_bytes;        /* RAW network bytes that generated this request - if known. */
     int http_status;            /* Store a possible HTTP status code that gets
                                  * defined before creating the dummy HTTP/1.1
index 3be237ef34a02d4f92dd690a96a302db4ecfde5b..3e4b1e855efc0beca15eacfd6dd447498006567b 100644 (file)
@@ -442,7 +442,6 @@ static apr_status_t append_bucket(h2_bucket_beam *beam,
         APR_BUCKET_REMOVE(b);
         apr_bucket_setaside(b, beam->pool);
         H2_BLIST_INSERT_TAIL(&beam->buckets_to_send, b);
-        *pwritten += (apr_off_t)b->length;
         goto cleanup;
     }
     /* non meta bucket */
index a23c6d2e6d3f37bb3e4cf8e60e93266a7155a57a..fd0adb51c68968814824cf13d5650e870d1269c3 100644 (file)
@@ -416,16 +416,32 @@ receive:
 
 static apr_status_t beam_out(conn_rec *c2, h2_conn_ctx_t *conn_ctx, apr_bucket_brigade* bb)
 {
-    apr_off_t written;
+    apr_off_t written, header_len = 0;
     apr_status_t rv;
 
+    if (h2_c2_logio_add_bytes_out) {
+        /* mod_logio wants to report the number of bytes  written in a
+         * response, including header and footer fields. Since h2 converts
+         * those during c1 processing into the HPACKed h2 HEADER frames,
+         * we need to give mod_logio something here and count just the
+         * raw lengths of all headers in the buckets. */
+        apr_bucket *b;
+        for (b = APR_BRIGADE_FIRST(bb);
+             b != APR_BRIGADE_SENTINEL(bb);
+             b = APR_BUCKET_NEXT(b)) {
+            if (H2_BUCKET_IS_HEADERS(b)) {
+                header_len += (apr_off_t)h2_bucket_headers_headers_length(b);
+            }
+        }
+    }
+
     rv = h2_beam_send(conn_ctx->beam_out, c2, bb, APR_BLOCK_READ, &written);
 
     if (APR_STATUS_IS_EAGAIN(rv)) {
         rv = APR_SUCCESS;
     }
     if (written && h2_c2_logio_add_bytes_out) {
-        h2_c2_logio_add_bytes_out(c2, written);
+        h2_c2_logio_add_bytes_out(c2, written + header_len);
     }
     return rv;
 }
index 29d86fdff2fdf712c7ffbbe3cc6d6488bf281c87..c1a6a8c333274983c8e7ae8ec7c638871bfb26d4 100644 (file)
@@ -64,7 +64,7 @@ apr_bucket * h2_bucket_headers_make(apr_bucket *b, h2_headers *r)
 
     b = apr_bucket_shared_make(b, br, 0, 0);
     b->type = &h2_bucket_type_headers;
-    b->length = h2_headers_length(r);
+    b->length = 0;
     
     return b;
 } 
@@ -140,6 +140,12 @@ apr_size_t h2_headers_length(h2_headers *headers)
     return len;
 }
 
+apr_size_t h2_bucket_headers_headers_length(apr_bucket *b)
+{
+    h2_headers *h = h2_bucket_headers_get(b);
+    return h? h2_headers_length(h) : 0;
+}
+
 h2_headers *h2_headers_rcreate(request_rec *r, int status,
                                const apr_table_t *header, apr_pool_t *pool)
 {
index fbaf68785f4305199845c3a4f23ef1cb72362320..34b08cd76ceb025c93a3f54d34f8959ec5d25546 100644 (file)
@@ -77,7 +77,7 @@ h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h);
  * @param pool the memory pool to use
  */
 h2_headers *h2_headers_die(apr_status_t type,
-                             const struct h2_request *req, apr_pool_t *pool);
+                           const struct h2_request *req, apr_pool_t *pool);
 
 int h2_headers_are_response(h2_headers *headers);
 
@@ -86,4 +86,10 @@ int h2_headers_are_response(h2_headers *headers);
  */
 apr_size_t h2_headers_length(h2_headers *headers);
 
+/**
+ * For H2HEADER buckets, return the length of all contained header strings.
+ * For all other buckets, return 0.
+ */
+apr_size_t h2_bucket_headers_headers_length(apr_bucket *b);
+
 #endif /* defined(__mod_h2__h2_headers__) */
index 564c87ddc3ac079c370b99628b09922cbf2ffd43..d3c21c4f958f5061d2755a23e323ec07d58ab899 100644 (file)
@@ -140,7 +140,7 @@ class TestStore:
         assert 0 == len(promises)
 
     # 2 H2PushResource config trigger on GET, but not on POST
-    def test_h2_400_20(self, env):
+    def test_h2_400_20(self, env, repeat):
         url = env.mkurl("https", "push", "/006-push20.html")
         r = env.nghttp().get(url)
         assert 200 == r.response["status"]