]> git.kaiwu.me - nginx.git/commitdiff
HTTP/2: fixed flushing early hints over SSL.
authorRoman Arutyunyan <arut@nginx.com>
Thu, 24 Jul 2025 14:29:21 +0000 (18:29 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Mon, 28 Jul 2025 17:06:48 +0000 (21:06 +0400)
Previously, when using HTTP/2 over SSL, an early hints HEADERS frame was
queued in SSL buffer, and might not be immediately flushed.  This resulted
in a delay of early hints delivery until the main response was sent.

The fix is to set the flush flag for the early hints HEADERS frame buffer.

src/http/v2/ngx_http_v2_filter_module.c

index 907906a88bc2547a4d0295fa3ad11c1aec302569..6b73b1e6876915478df765bd65662ec640944fc3 100644 (file)
@@ -32,7 +32,8 @@ static ngx_int_t ngx_http_v2_early_hints_filter(ngx_http_request_t *r);
 static ngx_int_t ngx_http_v2_init_stream(ngx_http_request_t *r);
 
 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
-    ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin);
+    ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin,
+    ngx_uint_t flush);
 static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
     ngx_http_request_t *r);
 
@@ -609,7 +610,7 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
     fin = r->header_only
           || (r->headers_out.content_length_n == 0 && !r->expect_trailers);
 
-    frame = ngx_http_v2_create_headers_frame(r, start, pos, fin);
+    frame = ngx_http_v2_create_headers_frame(r, start, pos, fin, 0);
     if (frame == NULL) {
         return NGX_ERROR;
     }
@@ -774,7 +775,7 @@ ngx_http_v2_early_hints_filter(ngx_http_request_t *r)
                                       header[i].value.len, tmp);
     }
 
-    frame = ngx_http_v2_create_headers_frame(r, start, pos, 0);
+    frame = ngx_http_v2_create_headers_frame(r, start, pos, 0, 1);
     if (frame == NULL) {
         return NGX_ERROR;
     }
@@ -825,7 +826,7 @@ ngx_http_v2_init_stream(ngx_http_request_t *r)
 
 static ngx_http_v2_out_frame_t *
 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
-    u_char *end, ngx_uint_t fin)
+    u_char *end, ngx_uint_t fin, ngx_uint_t flush)
 {
     u_char                    type, flags;
     size_t                    rest, frame_size;
@@ -916,6 +917,7 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
         }
 
         b->last_buf = fin;
+        b->flush = flush;
         cl->next = NULL;
         frame->last = cl;
 
@@ -1038,7 +1040,7 @@ ngx_http_v2_create_trailers_frame(ngx_http_request_t *r)
                                       header[i].value.len, tmp);
     }
 
-    return ngx_http_v2_create_headers_frame(r, start, pos, 1);
+    return ngx_http_v2_create_headers_frame(r, start, pos, 1, 0);
 }