]> git.feebdaed.xyz Git - 0xmirror/nginx.git/commitdiff
Added $request_port and $is_request_port variables.
authorRoman Arutyunyan <arut@nginx.com>
Mon, 29 Sep 2025 16:47:27 +0000 (20:47 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Thu, 23 Oct 2025 14:40:05 +0000 (18:40 +0400)
The $request_port variable contains the port passed by the client in the
request line (for HTTP/1.x) or ":authority" pseudo-header (for HTTP/2 and
HTTP/3).  If the request line contains no host, or ":authority" is missing,
then $request_port is taken from the "Host" header, similar to the $host
variable.

The $is_request_port variable contains ":" if $request_port is non-empty,
and is empty otherwise.

src/http/ngx_http_parse.c
src/http/ngx_http_request.c
src/http/ngx_http_request.h
src/http/ngx_http_variables.c
src/http/v2/ngx_http_v2.c
src/http/v3/ngx_http_v3_request.c

index a45c04554b42baccbefd4d1789e31247645b3630..68f604e10e56a7656f76cdace98bd9ca3d231c8a 100644 (file)
@@ -446,6 +446,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
 
         case sw_port:
             if (ch >= '0' && ch <= '9') {
+                if (r->port >= 6553 && (r->port > 6553 || (ch - '0') > 5)) {
+                    return NGX_HTTP_PARSE_INVALID_REQUEST;
+                }
+
+                r->port = r->port * 10 + (ch - '0');
                 break;
             }
 
index 16d79c490d752311e601257c26e6217fae8e0655..7f2d04783b76afdc5570ae4c3cd72c44c2662048 100644 (file)
@@ -1846,8 +1846,9 @@ static ngx_int_t
 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    ngx_int_t  rc;
-    ngx_str_t  host;
+    u_char     *p;
+    ngx_int_t   rc;
+    ngx_str_t   host;
 
     if (r->headers_in.host) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
@@ -1888,6 +1889,17 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
 
     r->headers_in.server = host;
 
+    p = ngx_strlchr(h->value.data + host.len,
+                    h->value.data + h->value.len, ':');
+
+    if (p) {
+        rc = ngx_atoi(p + 1, h->value.data + h->value.len - p - 1);
+
+        if (rc > 0 && rc < 65536) {
+            r->port = rc;
+        }
+    }
+
     return NGX_OK;
 }
 
index ad11f147f700957d99ff9ced540f87eb694ebe4e..1b012f8109aa102a34562a9204bcb7761d6db971 100644 (file)
@@ -461,6 +461,8 @@ struct ngx_http_request_s {
 
     ngx_http_cleanup_t               *cleanup;
 
+    in_port_t                         port;
+
     unsigned                          count:16;
     unsigned                          subrequests:8;
     unsigned                          blocked:8;
index 4f0bd0e4b0b8471502beb15941de91acee57d5a7..dd69bcfcd2022f0f407e28bb5f2b17e2a677ddfd 100644 (file)
@@ -71,6 +71,10 @@ static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_port(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_is_request_port(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static void ngx_http_variable_set_args(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
@@ -231,6 +235,12 @@ static ngx_http_variable_t  ngx_http_core_variables[] = {
 
     { ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
 
+    { ngx_string("request_port"), NULL,
+      ngx_http_variable_request_port, 0, 0, 0 },
+
+    { ngx_string("is_request_port"), NULL,
+      ngx_http_variable_is_request_port, 0, 0, 0 },
+
     { ngx_string("request_uri"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
 
@@ -1540,6 +1550,51 @@ ngx_http_variable_https(ngx_http_request_t *r,
 }
 
 
+static ngx_int_t
+ngx_http_variable_request_port(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    ngx_uint_t  port;
+
+    v->len = 0;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+
+    v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
+    if (v->data == NULL) {
+        return NGX_ERROR;
+    }
+
+    port = r->port;
+
+    if (port > 0 && port < 65536) {
+        v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_is_request_port(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    if (r->port == 0) {
+        *v = ngx_http_variable_null_value;
+        return NGX_OK;
+    }
+
+    v->len = 1;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = (u_char *) ":";
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_http_variable_set_args(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
index 13856583f810c21b66b93edd5469d12afae4c67c..fe9ee5a881e29c82ca9a16de3e66e56491f16533 100644 (file)
@@ -3518,7 +3518,8 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value)
 static ngx_int_t
 ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
 {
-    ngx_int_t  rc;
+    u_char     *p;
+    ngx_int_t   rc;
 
     if (r->host_start) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
@@ -3552,6 +3553,16 @@ ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
 
     r->headers_in.server = *value;
 
+    p = ngx_strlchr(r->host_start + value->len, r->host_end, ':');
+
+    if (p) {
+        rc = ngx_atoi(p + 1, r->host_end - p - 1);
+
+        if (rc > 0 && rc < 65536) {
+            r->port = rc;
+        }
+    }
+
     return NGX_OK;
 }
 
index 844a4000a8563ab390385d8e36010badb383c438..77c55bfeec95ec8ff0fa19f4bcb6c0687e6b8c40 100644 (file)
@@ -979,6 +979,16 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
         }
 
         r->headers_in.server = host;
+
+        p = ngx_strlchr(r->host_start + host.len, r->host_end, ':');
+
+        if (p) {
+            rc = ngx_atoi(p + 1, r->host_end - p - 1);
+
+            if (rc > 0 && rc < 65536) {
+                r->port = rc;
+            }
+        }
     }
 
     if (ngx_list_init(&r->headers_in.headers, r->pool, 20,