# HG changeset patch # User Roman Arutyunyan # Date 1584619389 -10800 # Node ID a3257a725b3d94bf79b38abe5837a7aefa512558 # Parent ff540f13d95df30dc83f4074e391d45c44f21eba Fixed header creation for header_only responses in HTTP/3. diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- 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; diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c --- 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;