Mercurial > hg > ngx_http_auth_request_module
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 } |