comparison src/http/ngx_http_core_module.c @ 3325:42c16d8bddbe

regex named captures
author Igor Sysoev <igor@sysoev.ru>
date Mon, 16 Nov 2009 12:19:02 +0000
parents 48402deff89a
children d8228f0b5113
comparison
equal deleted inserted replaced
3324:616da2ea901f 3325:42c16d8bddbe
1418 ngx_http_core_find_location(ngx_http_request_t *r) 1418 ngx_http_core_find_location(ngx_http_request_t *r)
1419 { 1419 {
1420 ngx_int_t rc; 1420 ngx_int_t rc;
1421 ngx_http_core_loc_conf_t *pclcf; 1421 ngx_http_core_loc_conf_t *pclcf;
1422 #if (NGX_PCRE) 1422 #if (NGX_PCRE)
1423 ngx_int_t n, len; 1423 ngx_int_t n;
1424 ngx_uint_t noregex; 1424 ngx_uint_t noregex;
1425 ngx_http_core_loc_conf_t *clcf, **clcfp; 1425 ngx_http_core_loc_conf_t *clcf, **clcfp;
1426 1426
1427 noregex = 0; 1427 noregex = 0;
1428 #endif 1428 #endif
1452 1452
1453 #if (NGX_PCRE) 1453 #if (NGX_PCRE)
1454 1454
1455 if (noregex == 0 && pclcf->regex_locations) { 1455 if (noregex == 0 && pclcf->regex_locations) {
1456 1456
1457 len = 0;
1458
1459 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { 1457 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
1460 1458
1461 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1459 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1462 "test location: ~ \"%V\"", &(*clcfp)->name); 1460 "test location: ~ \"%V\"", &(*clcfp)->name);
1463 1461
1464 if ((*clcfp)->captures) { 1462 n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
1465 1463
1466 len = (NGX_HTTP_MAX_CAPTURES + 1) * 3; 1464 if (n == NGX_OK) {
1467 1465 r->loc_conf = (*clcfp)->loc_conf;
1468 if (r->captures == NULL) { 1466
1469 r->captures = ngx_palloc(r->pool, len * sizeof(int)); 1467 /* look up nested locations */
1470 if (r->captures == NULL) { 1468
1471 return NGX_ERROR; 1469 rc = ngx_http_core_find_location(r);
1472 } 1470
1473 } 1471 return (rc == NGX_ERROR) ? rc : NGX_OK;
1474 } 1472 }
1475 1473
1476 n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len); 1474 if (n == NGX_DECLINED) {
1477
1478 if (n == NGX_REGEX_NO_MATCHED) {
1479 continue; 1475 continue;
1480 } 1476 }
1481 1477
1482 if (n < 0) { 1478 return NGX_ERROR;
1483 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1484 ngx_regex_exec_n
1485 " failed: %d on \"%V\" using \"%V\"",
1486 n, &r->uri, &(*clcfp)->name);
1487 return NGX_ERROR;
1488 }
1489
1490 /* match */
1491
1492 r->loc_conf = (*clcfp)->loc_conf;
1493
1494 r->ncaptures = len;
1495 r->captures_data = r->uri.data;
1496
1497 /* look up nested locations */
1498
1499 rc = ngx_http_core_find_location(r);
1500
1501 return (rc == NGX_ERROR) ? rc : NGX_OK;
1502 } 1479 }
1503 } 1480 }
1504 #endif 1481 #endif
1505 1482
1506 return rc; 1483 return rc;
1776 } else { 1753 } else {
1777 1754
1778 #if (NGX_PCRE) 1755 #if (NGX_PCRE)
1779 ngx_uint_t captures; 1756 ngx_uint_t captures;
1780 1757
1781 captures = alias && clcf->captures; 1758 captures = alias && clcf->regex;
1782 reserved += captures ? 1 : r->uri.len - alias + 1; 1759 reserved += captures ? 1 : r->uri.len - alias + 1;
1783 #else 1760 #else
1784 reserved += r->uri.len - alias + 1; 1761 reserved += r->uri.len - alias + 1;
1785 #endif 1762 #endif
1786 1763
2594 static ngx_int_t 2571 static ngx_int_t
2595 ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf, 2572 ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
2596 ngx_str_t *regex, ngx_uint_t caseless) 2573 ngx_str_t *regex, ngx_uint_t caseless)
2597 { 2574 {
2598 #if (NGX_PCRE) 2575 #if (NGX_PCRE)
2599 ngx_str_t err; 2576 ngx_regex_compile_t rc;
2600 u_char errstr[NGX_MAX_CONF_ERRSTR]; 2577 u_char errstr[NGX_MAX_CONF_ERRSTR];
2601 2578
2602 err.len = NGX_MAX_CONF_ERRSTR; 2579 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
2603 err.data = errstr; 2580
2581 rc.pattern = *regex;
2582 rc.err.len = NGX_MAX_CONF_ERRSTR;
2583 rc.err.data = errstr;
2604 2584
2605 #if (NGX_HAVE_CASELESS_FILESYSTEM) 2585 #if (NGX_HAVE_CASELESS_FILESYSTEM)
2606 caseless = 1; 2586 rc.options = NGX_REGEX_CASELESS;
2607 #endif 2587 #endif
2608 2588
2609 clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0, 2589 clcf->regex = ngx_http_regex_compile(cf, &rc);
2610 cf->pool, &err);
2611
2612 if (clcf->regex == NULL) { 2590 if (clcf->regex == NULL) {
2613 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
2614 return NGX_ERROR; 2591 return NGX_ERROR;
2615 } 2592 }
2616 2593
2617 clcf->name = *regex; 2594 clcf->name = *regex;
2618 clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0);
2619 2595
2620 return NGX_OK; 2596 return NGX_OK;
2621 2597
2622 #else 2598 #else
2623 2599
3533 continue; 3509 continue;
3534 } 3510 }
3535 3511
3536 #if (NGX_PCRE) 3512 #if (NGX_PCRE)
3537 { 3513 {
3538 ngx_str_t err; 3514 ngx_regex_compile_t rc;
3539 u_char errstr[NGX_MAX_CONF_ERRSTR]; 3515 u_char errstr[NGX_MAX_CONF_ERRSTR];
3540 3516
3541 if (value[i].len == 1) { 3517 if (value[i].len == 1) {
3542 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3518 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3543 "empty regex in server name \"%V\"", &value[i]); 3519 "empty regex in server name \"%V\"", &value[i]);
3544 return NGX_CONF_ERROR; 3520 return NGX_CONF_ERROR;
3545 } 3521 }
3546 3522
3547 err.len = NGX_MAX_CONF_ERRSTR;
3548 err.data = errstr;
3549
3550 value[i].len--; 3523 value[i].len--;
3551 value[i].data++; 3524 value[i].data++;
3552 3525
3553 sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err); 3526 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
3554 3527
3528 rc.pattern = value[i];
3529 rc.err.len = NGX_MAX_CONF_ERRSTR;
3530 rc.err.data = errstr;
3531
3532 sn->regex = ngx_http_regex_compile(cf, &rc);
3555 if (sn->regex == NULL) { 3533 if (sn->regex == NULL) {
3556 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
3557 return NGX_CONF_ERROR; 3534 return NGX_CONF_ERROR;
3558 } 3535 }
3559 3536
3560 sn->name = value[i]; 3537 sn->name = value[i];
3561 cscf->captures = (ngx_regex_capture_count(sn->regex) > 0); 3538 cscf->captures = (rc.captures > 0);
3562 } 3539 }
3563 #else 3540 #else
3564 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3541 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3565 "the using of the regex \"%V\" " 3542 "the using of the regex \"%V\" "
3566 "requires PCRE library", &value[i]); 3543 "requires PCRE library", &value[i]);
3662 3639
3663 if (ngx_http_script_compile(&sc) != NGX_OK) { 3640 if (ngx_http_script_compile(&sc) != NGX_OK) {
3664 return NGX_CONF_ERROR; 3641 return NGX_CONF_ERROR;
3665 } 3642 }
3666 } 3643 }
3667
3668 #if (NGX_PCRE)
3669
3670 if (alias && clcf->regex
3671 && (ngx_regex_capture_count(clcf->regex) <= 0 || sc.ncaptures == 0))
3672 {
3673 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3674 "the \"alias\" directive must use captures "
3675 "inside location given by regular expression");
3676
3677 return NGX_CONF_ERROR;
3678 }
3679
3680 #endif
3681 3644
3682 return NGX_CONF_OK; 3645 return NGX_CONF_OK;
3683 } 3646 }
3684 3647
3685 3648
4233 { 4196 {
4234 ngx_http_core_loc_conf_t *clcf = conf; 4197 ngx_http_core_loc_conf_t *clcf = conf;
4235 4198
4236 #if (NGX_PCRE) 4199 #if (NGX_PCRE)
4237 4200
4238 ngx_str_t err, *value; 4201 ngx_str_t *value;
4239 ngx_uint_t i; 4202 ngx_uint_t i;
4240 ngx_regex_elt_t *re; 4203 ngx_regex_elt_t *re;
4241 u_char errstr[NGX_MAX_CONF_ERRSTR]; 4204 ngx_regex_compile_t rc;
4205 u_char errstr[NGX_MAX_CONF_ERRSTR];
4242 4206
4243 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) { 4207 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
4244 clcf->gzip_disable = ngx_array_create(cf->pool, 2, 4208 clcf->gzip_disable = ngx_array_create(cf->pool, 2,
4245 sizeof(ngx_regex_elt_t)); 4209 sizeof(ngx_regex_elt_t));
4246 if (clcf->gzip_disable == NULL) { 4210 if (clcf->gzip_disable == NULL) {
4248 } 4212 }
4249 } 4213 }
4250 4214
4251 value = cf->args->elts; 4215 value = cf->args->elts;
4252 4216
4253 err.len = NGX_MAX_CONF_ERRSTR; 4217 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
4254 err.data = errstr; 4218
4219 rc.pool = cf->pool;
4220 rc.err.len = NGX_MAX_CONF_ERRSTR;
4221 rc.err.data = errstr;
4255 4222
4256 for (i = 1; i < cf->args->nelts; i++) { 4223 for (i = 1; i < cf->args->nelts; i++) {
4257 4224
4258 if (ngx_strcmp(value[1].data, "msie6") == 0) { 4225 if (ngx_strcmp(value[1].data, "msie6") == 0) {
4259 clcf->gzip_disable_msie6 = 1; 4226 clcf->gzip_disable_msie6 = 1;
4263 re = ngx_array_push(clcf->gzip_disable); 4230 re = ngx_array_push(clcf->gzip_disable);
4264 if (re == NULL) { 4231 if (re == NULL) {
4265 return NGX_CONF_ERROR; 4232 return NGX_CONF_ERROR;
4266 } 4233 }
4267 4234
4268 re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool, 4235 rc.pattern = value[1];
4269 &err); 4236 rc.options = NGX_REGEX_CASELESS;
4270 4237
4271 if (re->regex == NULL) { 4238 if (ngx_regex_compile(&rc) != NGX_OK) {
4272 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); 4239 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
4273 return NGX_CONF_ERROR; 4240 return NGX_CONF_ERROR;
4274 } 4241 }
4275 4242
4243 re->regex = rc.regex;
4276 re->name = value[i].data; 4244 re->name = value[i].data;
4277 } 4245 }
4278 4246
4279 return NGX_CONF_OK; 4247 return NGX_CONF_OK;
4280 4248