Klaus Demo nginx / 17f0e66
use complex value in error_page Igor Sysoev 13 years ago
4 changed file(s) with 53 addition(s) and 104 deletion(s). Raw diff Collapse all Expand all
3434 #include <ngx_http_upstream_round_robin.h>
3535 #include <ngx_http_config.h>
3636 #include <ngx_http_busy_lock.h>
37 #include <ngx_http_script.h>
3738 #include <ngx_http_core_module.h>
38 #include <ngx_http_script.h>
3939
4040 #if (NGX_HTTP_SSI)
4141 #include <ngx_http_ssi_filter_module.h>
37903790 {
37913791 ngx_http_core_loc_conf_t *lcf = conf;
37923792
3793 u_char *args;
3794 ngx_int_t overwrite;
3795 ngx_str_t *value, uri;
3796 ngx_uint_t i, n, nvar;
3797 ngx_array_t *uri_lengths, *uri_values;
3798 ngx_http_err_page_t *err;
3799 ngx_http_script_compile_t sc;
3793 u_char *p;
3794 ngx_int_t overwrite;
3795 ngx_str_t *value, uri, args;
3796 ngx_uint_t i, n;
3797 ngx_http_err_page_t *err;
3798 ngx_http_complex_value_t cv;
3799 ngx_http_compile_complex_value_t ccv;
38003800
38013801 if (lcf->error_pages == NULL) {
38023802 lcf->error_pages = ngx_array_create(cf->pool, 4,
38383838 }
38393839
38403840 uri = value[cf->args->nelts - 1];
3841 uri_lengths = NULL;
3842 uri_values = NULL;
3843
3844 nvar = ngx_http_script_variables_count(&uri);
3845
3846 if (nvar) {
3847 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3848
3849 sc.cf = cf;
3850 sc.source = &uri;
3851 sc.lengths = &uri_lengths;
3852 sc.values = &uri_values;
3853 sc.variables = nvar;
3854 sc.complete_lengths = 1;
3855 sc.complete_values = 1;
3856
3857 if (ngx_http_script_compile(&sc) != NGX_OK) {
3858 return NGX_CONF_ERROR;
3859 }
3860 }
3861
3862 args = (u_char *) ngx_strchr(uri.data, '?');
3841
3842 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
3843
3844 ccv.cf = cf;
3845 ccv.value = &uri;
3846 ccv.complex_value = &cv;
3847
3848 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
3849 return NGX_CONF_ERROR;
3850 }
3851
3852 args.len = 0;
3853 args.data = NULL;
3854
3855 if (cv.lengths == NULL) {
3856 p = (u_char *) ngx_strchr(uri.data, '?');
3857
3858 if (p) {
3859 cv.value.len = p - uri.data;
3860 cv.value.data = uri.data;
3861 p++;
3862 args.len = (uri.data + uri.len) - p;
3863 args.data = p;
3864 }
3865 }
38633866
38643867 for (i = 1; i < cf->args->nelts - n; i++) {
38653868 err = ngx_array_push(lcf->error_pages);
38993902 }
39003903 }
39013904
3902 if (args) {
3903 err->uri.len = args - uri.data;
3904 err->uri.data = uri.data;
3905 args++;
3906 err->args.len = (uri.data + uri.len) - args;
3907 err->args.data = args;
3908
3909 } else {
3910 err->uri = uri;
3911 err->args.len = 0;
3912 err->args.data = NULL;
3913 }
3914
3915 err->uri_lengths = uri_lengths;
3916 err->uri_values = uri_values;
3905 err->value = cv;
3906 err->args = args;
39173907 }
39183908
39193909 return NGX_CONF_OK;
257257 typedef struct {
258258 ngx_int_t status;
259259 ngx_int_t overwrite;
260 ngx_str_t uri;
260 ngx_http_complex_value_t value;
261261 ngx_str_t args;
262 ngx_array_t *uri_lengths;
263 ngx_array_t *uri_values;
264262 } ngx_http_err_page_t;
265263
266264
431431 static ngx_int_t
432432 ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
433433 {
434 u_char ch, *p, *last;
435434 ngx_int_t overwrite;
436 ngx_str_t *uri, *args, u, a;
435 ngx_str_t uri, args;
437436 ngx_table_elt_t *location;
438437 ngx_http_core_loc_conf_t *clcf;
439438
447446
448447 r->zero_in_uri = 0;
449448
450 if (err_page->uri_lengths) {
451 if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
452 err_page->uri_values->elts)
453 == NULL)
454 {
455 return NGX_ERROR;
456 }
457
458 p = u.data;
459 uri = &u;
460 args = NULL;
461
462 if (*p == '/') {
463
464 last = p + uri->len;
465
466 while (p < last) {
467
468 ch = *p++;
469
470 if (ch == '?') {
471 a.len = last - p;
472 a.data = p;
473 args = &a;
474
475 u.len = p - 1 - u.data;
476
477 while (p < last) {
478 if (*p++ == '\0') {
479 r->zero_in_uri = 1;
480 break;
481 }
482 }
483
484 break;
485 }
486
487 if (ch == '\0') {
488 r->zero_in_uri = 1;
489 continue;
490 }
491 }
492 }
449 if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
450 return NGX_ERROR;
451 }
452
453 if (err_page->value.lengths) {
454 ngx_http_split_args(r, &uri, &args);
493455
494456 } else {
495 uri = &err_page->uri;
496 args = &err_page->args;
497 }
498
499 if (uri->data[0] == '/') {
457 args = err_page->args;
458 }
459
460 if (uri.data[0] == '/') {
500461
501462 if (r->method != NGX_HTTP_HEAD) {
502463 r->method = NGX_HTTP_GET;
503464 r->method_name = ngx_http_get_name;
504465 }
505466
506 return ngx_http_internal_redirect(r, uri, args);
507 }
508
509 if (uri->data[0] == '@') {
510 return ngx_http_named_location(r, uri);
467 return ngx_http_internal_redirect(r, &uri, &args);
468 }
469
470 if (uri.data[0] == '@') {
471 return ngx_http_named_location(r, &uri);
511472 }
512473
513474 location = ngx_list_push(&r->headers_out.headers);
521482 location->hash = 1;
522483 location->key.len = sizeof("Location") - 1;
523484 location->key.data = (u_char *) "Location";
524 location->value = *uri;
485 location->value = uri;
525486
526487 r->headers_out.location = location;
527488