[auth_request] Add support for complex values in the auth_request directive value
Thomas P.
tpxp at live.fr
Mon Aug 5 07:51:36 UTC 2024
Hello,
It looks like my previous message did not make it to this list, so I'm resending it.
I'm building an app which makes use of auth_request to trigger some NJS code during the
processing of a request and its error handlers if any. I wanted to use some variables like
$upstream_code to tweak the JS script behaviour depending on whether I'm in a error
handler or not.
Some variables (like upstream_code) may not be available in the subrequest context, and
passing them through the URI is sufficient for my use case. So here's a changeset switching
nginx's interpretation of the auth_request value to a complex value, enabling use of any
variable in the value.
Another use case is to pass a location captured variable to the auth_request handler.
Thanks in advance for your review, I'll gladly answer any question and I hope this first
contribution isn't too bad (it's my first time with Mercurial so please bear with me).
Regards,
Thomas P.
# HG changeset patch
# User Thomas P. <tpxp at live.fr>
# Date 1722625005 -7200
# Fri Aug 02 20:56:45 2024 +0200
# Node ID 53d18e2171b9bdf4ca746c04d1503630fbaff9e1
# Parent d1b8568f3042f6019a2302dda4afbadd051fe54b
feat(auth_request): add support for complex values in auth_request
This changeset enables using variables in the value passed to the auth_request directive.
Since auth_request runs after the rewrite phase, this gives more flexibility to select
the location used for the authentication request, and enables passing additional
values that are not available in a subrequest context like $upstream_code (through the request URI).
diff -r d1b8568f3042 -r 53d18e2171b9 src/http/modules/ngx_http_auth_request_module.c
--- a/src/http/modules/ngx_http_auth_request_module.c Thu Jul 18 17:43:25 2024 +0400
+++ b/src/http/modules/ngx_http_auth_request_module.c Fri Aug 02 20:56:45 2024 +0200
@@ -11,7 +11,7 @@
typedef struct {
- ngx_str_t uri;
+ ngx_http_complex_value_t *uri;
ngx_array_t *vars;
} ngx_http_auth_request_conf_t;
@@ -101,6 +101,7 @@
static ngx_int_t
ngx_http_auth_request_handler(ngx_http_request_t *r)
{
+ ngx_str_t res;
ngx_table_elt_t *h, *ho, **ph;
ngx_http_request_t *sr;
ngx_http_post_subrequest_t *ps;
@@ -109,7 +110,7 @@
arcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_request_module);
- if (arcf->uri.len == 0) {
+ if (arcf->uri == NULL) {
return NGX_DECLINED;
}
@@ -192,7 +193,14 @@
ps->handler = ngx_http_auth_request_done;
ps->data = ctx;
- if (ngx_http_subrequest(r, &arcf->uri, NULL, &sr, ps,
+ if (ngx_http_complex_value(r, arcf->uri, &res) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "auth request uri evaluated to: %V", &res);
+
+ if (ngx_http_subrequest(r, &res, NULL, &sr, ps,
NGX_HTTP_SUBREQUEST_WAITED)
!= NGX_OK)
{
@@ -322,6 +330,7 @@
*/
conf->vars = NGX_CONF_UNSET_PTR;
+ conf->uri = NGX_CONF_UNSET_PTR;
return conf;
}
@@ -333,7 +342,7 @@
ngx_http_auth_request_conf_t *prev = parent;
ngx_http_auth_request_conf_t *conf = child;
- ngx_conf_merge_str_value(conf->uri, prev->uri, "");
+ ngx_conf_merge_ptr_value(conf->uri, prev->uri, NULL);
ngx_conf_merge_ptr_value(conf->vars, prev->vars, NULL);
return NGX_CONF_OK;
@@ -362,24 +371,40 @@
static char *
ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_auth_request_conf_t *arcf = conf;
+ ngx_http_auth_request_conf_t *arcf = conf;
+ ngx_http_complex_value_t *cv;
+ ngx_http_compile_complex_value_t ccv;
ngx_str_t *value;
- if (arcf->uri.data != NULL) {
+ if (arcf->uri != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
value = cf->args->elts;
if (ngx_strcmp(value[1].data, "off") == 0) {
- arcf->uri.len = 0;
- arcf->uri.data = (u_char *) "";
+ arcf->uri = NGX_CONF_UNSET_PTR;
return NGX_CONF_OK;
}
- arcf->uri = value[1];
+ cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (cv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = cv;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ arcf->uri = cv;
return NGX_CONF_OK;
}
More information about the nginx-devel
mailing list