Skip to content

HTTP/3: initialize Host header from :authority to enable $http_host variable#1

Open
MarcoMarcoaldi wants to merge 1 commit intomasterfrom
http3-http-host-header-from-authority
Open

HTTP/3: initialize Host header from :authority to enable $http_host variable#1
MarcoMarcoaldi wants to merge 1 commit intomasterfrom
http3-http-host-header-from-authority

Conversation

@MarcoMarcoaldi
Copy link
Owner

Description

Currently, when handling HTTP/3 (QUIC) requests, NGINX does not properly set
the $http_host variable. This is inconsistent with HTTP/1.1 and HTTP/2
handling and breaks compatibility with configurations relying on $http_host.

According to RFC 9114 Section 4.2:

If the :scheme pseudo-header field identifies a scheme that has a mandatory
authority component (including "http" and "https"), the request MUST contain
either an :authority pseudo-header field or a Host header field.
If both fields are present, they MUST contain the same value.

This patch initializes the Host header from the :authority pseudo-header
when it is missing, ensuring consistent behavior across all HTTP versions.

✅ Testing

The patch has been successfully tested in production on NGINX 1.29.1,
built with the --with-http_v3_module flag.

After applying the patch, $http_host is correctly set from :authority
for HTTP/3 requests.

🧩 Notes

This is a backward-compatible change aligned with RFC 9114 and mirrors HTTP/2’s
handling of the :authority field.

Note: Patch also sent to the official nginx-devel mailing list.


Full diff for reference:

diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
32a33,34
> static ngx_int_t ngx_http_v3_set_host(ngx_http_request_t *r, ngx_str_t *value); // Enable $http_host
> 
1001a1004,1032
> 
> ngx_http_v3_set_host(ngx_http_request_t *r, ngx_str_t *value)
> {
>     ngx_table_elt_t  *h;
> 
>     static ngx_str_t  host = ngx_string("host");
> 
>     h = ngx_list_push(&r->headers_in.headers);
>     if (h == NULL) {
>         return NGX_ERROR;
>     }
> 
>     h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');
> 
>     h->key.len = host.len;
>     h->key.data = host.data;
> 
>     h->value.len = value->len;
>     h->value.data = value->data;
> 
>     h->lowcase_key = host.data;
> 
>     r->headers_in.host = h;
>     h->next = NULL;
> 
>     return NGX_OK;
> }
> 
> static ngx_int_t
1038d1068
<     if (r->headers_in.host && r->host_end) {
1039a1070,1071
>  if (r->host_end) {
>         /* full :authority value (possibly with port) */
1043,1050c1075,1091
<         if (r->headers_in.host->value.len != host.len
<             || ngx_memcmp(r->headers_in.host->value.data, host.data, host.len)
<                != 0)
<         {
<             ngx_log_error(NGX_LOG_INFO, c->log, 0,
<                           "client sent \":authority\" and \"Host\" headers "
<                           "with different values");
<             goto failed;
---
>         if (r->headers_in.host) {
>             /* both Host and :authority present - ensure they are equal */
>             if (r->headers_in.host->value.len != host.len
>                 || ngx_memcmp(r->headers_in.host->value.data,
>                               host.data, host.len) != 0)
>             {
>                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
>                               "client sent \":authority\" and \"Host\" headers "
>                               "with different values");
>                 goto failed;
>             }
>         } else {
>             /* Host is missing - set from :authority */
>             if (ngx_http_v3_set_host(r, &host) != NGX_OK) {
>                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
>                 return NGX_ERROR;
>             }
1053a1095
> 
1491d1532
< 
1730a1772
> 

…ariable

This patch ensures that NGINX correctly initializes the HTTP Host header
from the :authority pseudo-header when handling HTTP/3 (QUIC) requests.

Currently, the $http_host variable is not set under HTTP/3, breaking
compatibility with configurations relying on it.

According to RFC 9114 Section 4.2, :authority and Host must have the same
value if both are present. This patch sets Host from :authority when missing,
ensuring consistent behavior across HTTP/1.1, HTTP/2, and HTTP/3.

Successfully tested in production.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant