changeset 8238:a3257a725b3d quic

Fixed header creation for header_only responses in HTTP/3.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 19 Mar 2020 15:03:09 +0300
parents ff540f13d95d
children 5ad7bffd3850
files src/http/ngx_http_header_filter_module.c src/http/v3/ngx_http_v3_request.c
diffstat 2 files changed, 31 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -179,6 +179,22 @@ ngx_http_header_filter(ngx_http_request_
         return NGX_OK;
     }
 
+    if (r->http_version < NGX_HTTP_VERSION_10) {
+        return NGX_OK;
+    }
+
+    if (r->method == NGX_HTTP_HEAD) {
+        r->header_only = 1;
+    }
+
+    if (r->headers_out.status_line.len == 0) {
+        if (r->headers_out.status == NGX_HTTP_NO_CONTENT
+            || r->headers_out.status == NGX_HTTP_NOT_MODIFIED)
+        {
+            r->header_only = 1;
+        }
+    }
+
 #if (NGX_HTTP_V3)
 
     if (r->http_version == NGX_HTTP_VERSION_30) {
@@ -194,14 +210,6 @@ ngx_http_header_filter(ngx_http_request_
 
 #endif
 
-    if (r->http_version < NGX_HTTP_VERSION_10) {
-        return NGX_OK;
-    }
-
-    if (r->method == NGX_HTTP_HEAD) {
-        r->header_only = 1;
-    }
-
     if (r->headers_out.last_modified_time != -1) {
         if (r->headers_out.status != NGX_HTTP_OK
             && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
@@ -235,7 +243,6 @@ ngx_http_header_filter(ngx_http_request_
             /* 2XX */
 
             if (status == NGX_HTTP_NO_CONTENT) {
-                r->header_only = 1;
                 ngx_str_null(&r->headers_out.content_type);
                 r->headers_out.last_modified_time = -1;
                 r->headers_out.last_modified = NULL;
@@ -252,10 +259,6 @@ ngx_http_header_filter(ngx_http_request_
         {
             /* 3XX */
 
-            if (status == NGX_HTTP_NOT_MODIFIED) {
-                r->header_only = 1;
-            }
-
             status = status - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX;
             status_line = &ngx_http_status_lines[status];
             len += ngx_http_status_lines[status].len;
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -259,7 +259,7 @@ ngx_http_v3_create_header(ngx_http_reque
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header");
 
     /* XXX support chunked body in the chunked filter */
-    if (r->headers_out.content_length_n == -1) {
+    if (!r->header_only && r->headers_out.content_length_n == -1) {
         return NULL;
     }
 
@@ -310,11 +310,11 @@ ngx_http_v3_create_header(ngx_http_reque
                + ngx_http_v3_encode_prefix_int(NULL, n, 7) + n;
     }
 
-    if (r->headers_out.content_length_n == 0) {
-        len += ngx_http_v3_encode_prefix_int(NULL, 4, 6);
+    if (r->headers_out.content_length_n > 0) {
+        len += ngx_http_v3_encode_prefix_int(NULL, 4, 4) + 1 + NGX_OFF_T_LEN;
 
-    } else {
-        len += ngx_http_v3_encode_prefix_int(NULL, 4, 4) + 1 + NGX_OFF_T_LEN;
+    } else if (r->headers_out.content_length_n == 0) {
+        len += ngx_http_v3_encode_prefix_int(NULL, 4, 6);
     }
 
     if (r->headers_out.last_modified == NULL
@@ -454,18 +454,18 @@ ngx_http_v3_create_header(ngx_http_reque
         }
     }
 
-    if (r->headers_out.content_length_n == 0) {
-        /* content-length: 0 */
-        *b->last = 0xc0;
-        b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 4, 6);
-
-    } else if (r->headers_out.content_length_n > 0) {
+    if (r->headers_out.content_length_n > 0) {
         /* content-length: 0 */
         *b->last = 0x70;
         b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 4, 4);
         p = b->last++;
         b->last = ngx_sprintf(b->last, "%O", r->headers_out.content_length_n);
         *p = b->last - p - 1;
+
+    } else if (r->headers_out.content_length_n == 0) {
+        /* content-length: 0 */
+        *b->last = 0xc0;
+        b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 4, 6);
     }
 
     if (r->headers_out.last_modified == NULL
@@ -521,6 +521,10 @@ ngx_http_v3_create_header(ngx_http_reque
         b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
     }
 
+    if (r->header_only) {
+        b->last_buf = 1;
+    }
+
     cl = ngx_alloc_chain_link(c->pool);
     if (cl == NULL) {
         return NULL;