Mercurial > hg > nginx-quic
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 |