[PATCH] implement a $location variable
David Gwynne
david at gwynne.id.au
Mon Oct 15 01:22:00 UTC 2012
this patch is actually from piotr sikora, and is part of coolkit already. this is just a port of it to stock nginx.
this makes the part of the request uri that matches the locations name available as a variable within a block. eg if you have location /foo { } and request /foo/bar/foo, $location will have the value /foo. if you have location ^~ /(foo|bar) and request /foo/bar/foo, $location will still have /foo in it. think of it as $0 for regex locations, but it works for non-regex location names too.
im running this in production now and its working great. it allows me to treat the locations name as a parameter to an applications front end controller without having to repeat the value within a location block.
cheers,
dlg
--- src/http/ngx_http_variables.c.orig Tue Jul 3 03:41:52 2012
+++ src/http/ngx_http_variables.c Thu Aug 23 10:32:22 2012
@@ -65,6 +65,8 @@ static ngx_int_t ngx_http_variable_request_filename(ng
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_server_name(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_location(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r,
@@ -206,6 +208,10 @@ static ngx_http_variable_t ngx_http_core_variables[]
{ ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },
+ { ngx_string("location"), NULL,
+ ngx_http_variable_location, 0,
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
{ ngx_string("request_method"), NULL,
ngx_http_variable_request_method, 0,
NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -1382,6 +1388,39 @@ ngx_http_variable_server_name(ngx_http_request_t *r,
v->no_cacheable = 0;
v->not_found = 0;
v->data = cscf->server_name.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_location(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_int_t rc;
+ int captures[3];
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->regex) {
+ rc = ngx_regex_exec(clcf->regex->regex, &r->uri, captures, 3);
+
+ if (rc == NGX_REGEX_NO_MATCHED) {
+ return NGX_ERROR;
+ }
+
+ v->data = r->uri.data + captures[0];
+ v->len = captures[1] - captures[0];
+
+ } else {
+ v->data = clcf->name.data;
+ v->len = clcf->name.len;
+ }
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
return NGX_OK;
}
More information about the nginx-devel
mailing list