extension to server_name directive - include top-level directory in search
Chris Newton
cnewton at netflix.com
Tue Jul 25 14:56:50 UTC 2023
The server_name directive allows for selecting which "server" block should
be used to process a request; a "server" being a very convenient way to
group a set of directives and location blocks into a separate and distinct
configuration entity. Currently, server_name selects the server based on
the value of the Host: header alone, which can be overly constraining.
The attached patch extends server_name to allow the first directory element
to be used as part of the selection process. When there is at least one
server_name with a '/' character, at ngx_http_find_virtual_server() time an
initial lookup into the virtual_names hash is made using a combination of
hostname/topleveldirectory - if no match is found, the hostname only lookup
is performed (as before), thereby allowing for specific directories to be
broken out into their own server blocks
>From a01fd492fb8935e9c9e0f4c703b9430c83c12590 Mon Sep 17 00:00:00 2001
From: Chris Newton <cnewton at netflix.com>
Date: Mon, 24 Jul 2023 19:32:03 +0000
Subject: [PATCH] virtual aliases
---
src/http/ngx_http.c | 2 ++
src/http/ngx_http.h | 1 +
src/http/ngx_http_core_module.c | 4 +--
src/http/ngx_http_request.c | 54 ++++++++++++++++++++++++++++-----
4 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index d835f896e..54ad9cb9e 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -70,6 +70,7 @@ static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf,
ngx_http_port_t *hport,
ngx_uint_t ngx_http_max_module;
+ngx_uint_t ngx_http_uses_complete_alias;
ngx_http_output_header_filter_pt ngx_http_top_header_filter;
ngx_http_output_body_filter_pt ngx_http_top_body_filter;
@@ -148,6 +149,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void
*conf)
ngx_http_max_module = ngx_count_modules(cf->cycle, NGX_HTTP_MODULE);
+ ngx_http_uses_complete_alias = 0;
/* the http main_conf context, it is the same in the all http contexts
*/
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index e06464ebd..935cecc0f 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -189,6 +189,7 @@ extern ngx_module_t ngx_http_module;
extern ngx_str_t ngx_http_html_default_types[];
+extern ngx_uint_t ngx_http_uses_complete_alias;
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
diff --git a/src/http/ngx_http_core_module.c
b/src/http/ngx_http_core_module.c
index 97a91aee2..3179d65a1 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -4380,9 +4380,7 @@ ngx_http_core_server_name(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf)
}
if (ngx_strchr(value[i].data, '/')) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "server name \"%V\" has suspicious symbols",
- &value[i]);
+ ngx_http_uses_complete_alias = 1;
}
sn = ngx_array_push(&cscf->server_names);
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index bd2be5eac..189500885 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2227,6 +2227,7 @@ ngx_http_set_virtual_server(ngx_http_request_t *r,
ngx_str_t *host)
ngx_http_connection_t *hc;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
+ ngx_str_t *find_host = host;
#if (NGX_SUPPRESS_WARN)
cscf = NULL;
@@ -2250,7 +2251,11 @@ ngx_http_set_virtual_server(ngx_http_request_t *r,
ngx_str_t *host)
return NGX_ERROR;
}
#endif
- return NGX_OK;
+ if (ngx_http_uses_complete_alias) {
+ find_host = hc->ssl_servername;
+ } else {
+ return NGX_OK;
+ }
}
}
@@ -2258,7 +2263,7 @@ ngx_http_set_virtual_server(ngx_http_request_t *r,
ngx_str_t *host)
rc = ngx_http_find_virtual_server(r->connection,
hc->addr_conf->virtual_names,
- host, r, &cscf);
+ find_host, r, &cscf);
if (rc == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -2275,14 +2280,19 @@ ngx_http_set_virtual_server(ngx_http_request_t *r,
ngx_str_t *host)
rc = NGX_OK;
}
- sscf = ngx_http_get_module_srv_conf(cscf->ctx,
ngx_http_ssl_module);
+ if (!ngx_http_uses_complete_alias
+ || hc->ssl_servername->len != host->len
+ || ngx_strncmp(hc->ssl_servername->data,
+ host->data, host->len) != 0) {
+ sscf = ngx_http_get_module_srv_conf(cscf->ctx,
ngx_http_ssl_module);
- if (sscf->verify) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ if (sscf->verify) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client attempted to request the server name "
"different from the one that was negotiated");
- ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
- return NGX_ERROR;
+ ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
+ return NGX_ERROR;
+ }
}
}
@@ -2314,6 +2324,36 @@ ngx_http_find_virtual_server(ngx_connection_t *c,
return NGX_DECLINED;
}
+ if (r && r->uri.len > 1 && r->pool) {
+ ngx_str_t combined;
+ u_char *p;
+
+ p = (u_char *)ngx_strchr(&r->uri.data[1], '/');
+ if (p) {
+ ngx_uint_t alias_len = p - r->uri.data;
+ if (alias_len > r->uri.len) {
+ /* No '/' in the path, so use entire thing */
+ alias_len = r->uri.len;
+ }
+ combined.len = host->len + alias_len;
+
+ combined.data = ngx_pnalloc(r->pool, combined.len);
+ if (combined.data == NULL) {
+ return NGX_ERROR;
+ }
+ ngx_memcpy(&combined.data[0], host->data, host->len);
+ ngx_memcpy(&combined.data[host->len], r->uri.data, alias_len);
+
+ cscf = ngx_hash_find_combined(&virtual_names->names,
+ ngx_hash_key(combined.data,
combined.len),
+ combined.data, combined.len);
+ if (cscf) {
+ *cscfp = cscf;
+ return NGX_OK;
+ }
+ }
+ }
+
cscf = ngx_hash_find_combined(&virtual_names->names,
ngx_hash_key(host->data, host->len),
host->data, host->len);
--
2.40.1
*Chris Newton* (he/him/his)
Open Connect | Content Delivery Architecture M: 805.444.0573 |
cnewton at netflix.com
111 Albright Way | Los Gatos, CA 95032
<https://maps.google.com/?q=111+Albright+Way%C2%A0%7C++Los+Gatos,+CA+95032&entry=gmail&source=g>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20230725/c1f74120/attachment-0001.htm>
More information about the nginx-devel
mailing list