[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