comparison ngx_http_auth_request_module.c @ 7:fb05a061532c

Auth request: auth_request_set directive.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 19 Mar 2010 22:16:30 +0300
parents 35f0ee7a3c28
children 2b95417a1715
comparison
equal deleted inserted replaced
6:70f3d876b569 7:fb05a061532c
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 10
11 11
12 typedef struct { 12 typedef struct {
13 ngx_str_t uri; 13 ngx_str_t uri;
14 ngx_array_t *vars;
14 } ngx_http_auth_request_conf_t; 15 } ngx_http_auth_request_conf_t;
15 16
16 typedef struct { 17 typedef struct {
17 ngx_uint_t done; 18 ngx_uint_t done;
18 ngx_uint_t status; 19 ngx_uint_t status;
19 ngx_http_request_t *subrequest; 20 ngx_http_request_t *subrequest;
20 } ngx_http_auth_request_ctx_t; 21 } ngx_http_auth_request_ctx_t;
21 22
23 typedef struct {
24 ngx_int_t index;
25 ngx_http_complex_value_t value;
26 ngx_http_set_variable_pt set_handler;
27 } ngx_http_auth_request_variable_t;
28
22 29
23 static ngx_int_t ngx_http_auth_request_handler(ngx_http_request_t *r); 30 static ngx_int_t ngx_http_auth_request_handler(ngx_http_request_t *r);
24 static ngx_int_t ngx_http_auth_request_done(ngx_http_request_t *r, 31 static ngx_int_t ngx_http_auth_request_done(ngx_http_request_t *r,
25 void *data, ngx_int_t rc); 32 void *data, ngx_int_t rc);
33 static ngx_int_t ngx_http_auth_request_set_variables(ngx_http_request_t *r,
34 ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx);
35 static ngx_int_t ngx_http_auth_request_variable(ngx_http_request_t *r,
36 ngx_http_variable_value_t *v, uintptr_t data);
26 static void *ngx_http_auth_request_create_conf(ngx_conf_t *cf); 37 static void *ngx_http_auth_request_create_conf(ngx_conf_t *cf);
27 static char *ngx_http_auth_request_merge_conf(ngx_conf_t *cf, 38 static char *ngx_http_auth_request_merge_conf(ngx_conf_t *cf,
28 void *parent, void *child); 39 void *parent, void *child);
29 static ngx_int_t ngx_http_auth_request_init(ngx_conf_t *cf); 40 static ngx_int_t ngx_http_auth_request_init(ngx_conf_t *cf);
30 static char *ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd, 41 static char *ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd,
31 void *conf); 42 void *conf);
43 static char *ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd,
44 void *conf);
32 45
33 46
34 static ngx_command_t ngx_http_auth_request_commands[] = { 47 static ngx_command_t ngx_http_auth_request_commands[] = {
35 48
36 { ngx_string("auth_request"), 49 { ngx_string("auth_request"),
37 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 50 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
38 ngx_http_auth_request, 51 ngx_http_auth_request,
52 NGX_HTTP_LOC_CONF_OFFSET,
53 0,
54 NULL },
55
56 { ngx_string("auth_request_set"),
57 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
58 ngx_http_auth_request_set,
39 NGX_HTTP_LOC_CONF_OFFSET, 59 NGX_HTTP_LOC_CONF_OFFSET,
40 0, 60 0,
41 NULL }, 61 NULL },
42 62
43 ngx_null_command 63 ngx_null_command
98 if (ctx != NULL) { 118 if (ctx != NULL) {
99 if (!ctx->done) { 119 if (!ctx->done) {
100 return NGX_AGAIN; 120 return NGX_AGAIN;
101 } 121 }
102 122
123 /*
124 * as soon as we are done - explicitly set variables to make
125 * sure they will be available after internal redirects
126 */
127
128 if (ngx_http_auth_request_set_variables(r, arcf, ctx) != NGX_OK) {
129 return NGX_ERROR;
130 }
131
132 /* return appropriate status */
133
103 if (ctx->status == NGX_HTTP_FORBIDDEN) { 134 if (ctx->status == NGX_HTTP_FORBIDDEN) {
104 return ctx->status; 135 return ctx->status;
105 } 136 }
106 137
107 if (ctx->status == NGX_HTTP_UNAUTHORIZED) { 138 if (ctx->status == NGX_HTTP_UNAUTHORIZED) {
183 214
184 return rc; 215 return rc;
185 } 216 }
186 217
187 218
219 static ngx_int_t
220 ngx_http_auth_request_set_variables(ngx_http_request_t *r,
221 ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx)
222 {
223 ngx_str_t val;
224 ngx_http_variable_t *v;
225 ngx_http_variable_value_t *vv;
226 ngx_http_auth_request_variable_t *av, *last;
227 ngx_http_core_main_conf_t *cmcf;
228
229 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
230 "auth request set variables");
231
232 if (arcf->vars == NULL) {
233 return NGX_OK;
234 }
235
236 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
237 v = cmcf->variables.elts;
238
239 av = arcf->vars->elts;
240 last = av + arcf->vars->nelts;
241
242 while (av < last) {
243 /*
244 * explicitly set new value to make sure it will be available after
245 * internal redirects
246 */
247
248 vv = &r->variables[av->index];
249
250 if (ngx_http_complex_value(ctx->subrequest, &av->value, &val)
251 != NGX_OK)
252 {
253 return NGX_ERROR;
254 }
255
256 vv->valid = 1;
257 vv->not_found = 0;
258 vv->data = val.data;
259 vv->len = val.len;
260
261 if (av->set_handler) {
262 /*
263 * set_handler only available in cmcf->variables_keys, so we store
264 * it explicitly
265 */
266
267 av->set_handler(r, vv, v[av->index].data);
268 }
269
270 av++;
271 }
272
273 return NGX_OK;
274 }
275
276
277 static ngx_int_t
278 ngx_http_auth_request_variable(ngx_http_request_t *r,
279 ngx_http_variable_value_t *v, uintptr_t data)
280 {
281 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
282 "auth request variable");
283
284 v->not_found = 1;
285
286 return NGX_OK;
287 }
288
289
188 static void * 290 static void *
189 ngx_http_auth_request_create_conf(ngx_conf_t *cf) 291 ngx_http_auth_request_create_conf(ngx_conf_t *cf)
190 { 292 {
191 ngx_http_auth_request_conf_t *conf; 293 ngx_http_auth_request_conf_t *conf;
192 294
199 * set by ngx_pcalloc(): 301 * set by ngx_pcalloc():
200 * 302 *
201 * conf->uri.len = { 0, NULL }; 303 * conf->uri.len = { 0, NULL };
202 */ 304 */
203 305
306 conf->vars = NGX_CONF_UNSET_PTR;
307
204 return conf; 308 return conf;
205 } 309 }
206 310
207 311
208 static char * 312 static char *
210 { 314 {
211 ngx_http_auth_request_conf_t *prev = parent; 315 ngx_http_auth_request_conf_t *prev = parent;
212 ngx_http_auth_request_conf_t *conf = child; 316 ngx_http_auth_request_conf_t *conf = child;
213 317
214 ngx_conf_merge_str_value(conf->uri, prev->uri, ""); 318 ngx_conf_merge_str_value(conf->uri, prev->uri, "");
319 ngx_conf_merge_ptr_value(conf->vars, prev->vars, NULL);
215 320
216 return NGX_CONF_OK; 321 return NGX_CONF_OK;
217 } 322 }
218 323
219 324
258 363
259 arcf->uri = value[1]; 364 arcf->uri = value[1];
260 365
261 return NGX_CONF_OK; 366 return NGX_CONF_OK;
262 } 367 }
368
369
370 static char *
371 ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
372 {
373 ngx_http_auth_request_conf_t *arcf = conf;
374
375 ngx_str_t *value;
376 ngx_http_variable_t *v;
377 ngx_http_auth_request_variable_t *av;
378 ngx_http_compile_complex_value_t ccv;
379
380 value = cf->args->elts;
381
382 if (value[1].data[0] != '$') {
383 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
384 "invalid variable name \"%V\"", &value[1]);
385 return NGX_CONF_ERROR;
386 }
387
388 value[1].len--;
389 value[1].data++;
390
391 if (arcf->vars == NGX_CONF_UNSET_PTR) {
392 arcf->vars = ngx_array_create(cf->pool, 1,
393 sizeof(ngx_http_auth_request_variable_t));
394 if (arcf->vars == NULL) {
395 return NGX_CONF_ERROR;
396 }
397 }
398
399 av = ngx_array_push(arcf->vars);
400 if (av == NULL) {
401 return NGX_CONF_ERROR;
402 }
403
404 v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
405 if (v == NULL) {
406 return NGX_CONF_ERROR;
407 }
408
409 av->index = ngx_http_get_variable_index(cf, &value[1]);
410 if (av->index == NGX_ERROR) {
411 return NGX_CONF_ERROR;
412 }
413
414 if (v->get_handler == NULL) {
415 v->get_handler = ngx_http_auth_request_variable;
416 v->data = (uintptr_t) av;
417 }
418
419 av->set_handler = v->set_handler;
420
421 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
422
423 ccv.cf = cf;
424 ccv.value = &value[2];
425 ccv.complex_value = &av->value;
426
427 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
428 return NGX_CONF_ERROR;
429 }
430
431 return NGX_CONF_OK;
432 }