Mercurial > hg > nginx-vendor-1-0
comparison src/http/ngx_http_core_module.c @ 456:ca8f7f6cab16 NGINX_0_7_40
nginx 0.7.40
*) Feature: the "location" directive supports captures in regular
expressions.
*) Feature: an "alias" directive with capture references may be used
inside a location given by a regular expression with captures.
*) Feature: the "server_name" directive supports captures in regular
expressions.
*) Workaround: the ngx_http_autoindex_module did not show the trailing
slash in directories on XFS filesystem; the issue had appeared in
0.7.15.
Thanks to Dmitry Kuzmenko.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 09 Mar 2009 00:00:00 +0300 |
parents | a8424ffa495c |
children | 2e2b57743e87 |
comparison
equal
deleted
inserted
replaced
455:ead634c4b006 | 456:ca8f7f6cab16 |
---|---|
1335 ngx_http_core_find_location(ngx_http_request_t *r) | 1335 ngx_http_core_find_location(ngx_http_request_t *r) |
1336 { | 1336 { |
1337 ngx_int_t rc; | 1337 ngx_int_t rc; |
1338 ngx_http_core_loc_conf_t *pclcf; | 1338 ngx_http_core_loc_conf_t *pclcf; |
1339 #if (NGX_PCRE) | 1339 #if (NGX_PCRE) |
1340 ngx_int_t n; | 1340 ngx_int_t n, len; |
1341 ngx_uint_t noregex; | 1341 ngx_uint_t noregex; |
1342 ngx_http_core_loc_conf_t *clcf, **clcfp; | 1342 ngx_http_core_loc_conf_t *clcf, **clcfp; |
1343 | 1343 |
1344 noregex = 0; | 1344 noregex = 0; |
1345 #endif | 1345 #endif |
1369 | 1369 |
1370 #if (NGX_PCRE) | 1370 #if (NGX_PCRE) |
1371 | 1371 |
1372 if (noregex == 0 && pclcf->regex_locations) { | 1372 if (noregex == 0 && pclcf->regex_locations) { |
1373 | 1373 |
1374 len = 0; | |
1375 | |
1374 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { | 1376 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { |
1375 | 1377 |
1376 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1378 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1377 "test location: ~ \"%V\"", &(*clcfp)->name); | 1379 "test location: ~ \"%V\"", &(*clcfp)->name); |
1378 | 1380 |
1379 n = ngx_regex_exec((*clcfp)->regex, &r->uri, NULL, 0); | 1381 if ((*clcfp)->captures && r->captures == NULL) { |
1382 | |
1383 len = (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int); | |
1384 | |
1385 r->captures = ngx_palloc(r->pool, len); | |
1386 if (r->captures == NULL) { | |
1387 return NGX_ERROR; | |
1388 } | |
1389 } | |
1390 | |
1391 n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len); | |
1380 | 1392 |
1381 if (n == NGX_REGEX_NO_MATCHED) { | 1393 if (n == NGX_REGEX_NO_MATCHED) { |
1382 continue; | 1394 continue; |
1383 } | 1395 } |
1384 | 1396 |
1392 | 1404 |
1393 /* match */ | 1405 /* match */ |
1394 | 1406 |
1395 r->loc_conf = (*clcfp)->loc_conf; | 1407 r->loc_conf = (*clcfp)->loc_conf; |
1396 | 1408 |
1409 r->ncaptures = len; | |
1410 r->captures_data = r->uri.data; | |
1411 | |
1397 /* look up nested locations */ | 1412 /* look up nested locations */ |
1398 | 1413 |
1399 rc = ngx_http_core_find_location(r); | 1414 rc = ngx_http_core_find_location(r); |
1400 | 1415 |
1401 return (rc == NGX_ERROR) ? rc : NGX_OK; | 1416 return (rc == NGX_ERROR) ? rc : NGX_OK; |
1684 return NULL; | 1699 return NULL; |
1685 } | 1700 } |
1686 | 1701 |
1687 *root_length = path->len - reserved; | 1702 *root_length = path->len - reserved; |
1688 last = path->data + *root_length; | 1703 last = path->data + *root_length; |
1704 | |
1705 if (alias) { | |
1706 *last = '\0'; | |
1707 return last; | |
1708 } | |
1689 } | 1709 } |
1690 | 1710 |
1691 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); | 1711 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); |
1692 | 1712 |
1693 return last; | 1713 return last; |
2532 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | 2552 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); |
2533 return NGX_ERROR; | 2553 return NGX_ERROR; |
2534 } | 2554 } |
2535 | 2555 |
2536 clcf->name = *regex; | 2556 clcf->name = *regex; |
2557 clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0); | |
2537 | 2558 |
2538 return NGX_OK; | 2559 return NGX_OK; |
2539 | 2560 |
2540 #else | 2561 #else |
2541 | 2562 |
2796 return NGX_CONF_ERROR; | 2817 return NGX_CONF_ERROR; |
2797 } | 2818 } |
2798 | 2819 |
2799 #if (NGX_PCRE) | 2820 #if (NGX_PCRE) |
2800 sn->regex = NULL; | 2821 sn->regex = NULL; |
2822 sn->captures = 0; | |
2801 #endif | 2823 #endif |
2802 sn->core_srv_conf = conf; | 2824 sn->core_srv_conf = conf; |
2803 sn->name.len = conf->server_name.len; | 2825 sn->name.len = conf->server_name.len; |
2804 sn->name.data = conf->server_name.data; | 2826 sn->name.data = conf->server_name.data; |
2805 } | 2827 } |
3397 return NGX_CONF_ERROR; | 3419 return NGX_CONF_ERROR; |
3398 } | 3420 } |
3399 | 3421 |
3400 #if (NGX_PCRE) | 3422 #if (NGX_PCRE) |
3401 sn->regex = NULL; | 3423 sn->regex = NULL; |
3424 sn->captures = 0; | |
3402 #endif | 3425 #endif |
3403 sn->core_srv_conf = cscf; | 3426 sn->core_srv_conf = cscf; |
3404 sn->name = value[i]; | 3427 sn->name = value[i]; |
3405 | 3428 |
3406 if (value[i].data[0] != '~') { | 3429 if (value[i].data[0] != '~') { |
3423 if (sn->regex == NULL) { | 3446 if (sn->regex == NULL) { |
3424 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | 3447 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); |
3425 return NGX_CONF_ERROR; | 3448 return NGX_CONF_ERROR; |
3426 } | 3449 } |
3427 | 3450 |
3451 sn->captures = (ngx_regex_capture_count(sn->regex) > 0); | |
3428 sn->name = value[i]; | 3452 sn->name = value[i]; |
3429 } | 3453 } |
3430 #else | 3454 #else |
3431 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 3455 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
3432 "the using of the regex \"%V\" " | 3456 "the using of the regex \"%V\" " |
3475 "inside named location"); | 3499 "inside named location"); |
3476 | 3500 |
3477 return NGX_CONF_ERROR; | 3501 return NGX_CONF_ERROR; |
3478 } | 3502 } |
3479 | 3503 |
3480 #if (NGX_PCRE) | |
3481 | |
3482 if (lcf->regex && alias) { | |
3483 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3484 "the \"alias\" directive may not be used " | |
3485 "inside location given by regular expression"); | |
3486 | |
3487 return NGX_CONF_ERROR; | |
3488 } | |
3489 | |
3490 #endif | |
3491 | |
3492 value = cf->args->elts; | 3504 value = cf->args->elts; |
3493 | 3505 |
3494 if (ngx_strstr(value[1].data, "$document_root") | 3506 if (ngx_strstr(value[1].data, "$document_root") |
3495 || ngx_strstr(value[1].data, "${document_root}")) | 3507 || ngx_strstr(value[1].data, "${document_root}")) |
3496 { | 3508 { |
3526 } | 3538 } |
3527 } | 3539 } |
3528 | 3540 |
3529 n = ngx_http_script_variables_count(&lcf->root); | 3541 n = ngx_http_script_variables_count(&lcf->root); |
3530 | 3542 |
3531 if (n == 0) { | |
3532 return NGX_CONF_OK; | |
3533 } | |
3534 | |
3535 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | 3543 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
3536 | 3544 |
3537 sc.cf = cf; | 3545 if (n) { |
3538 sc.source = &lcf->root; | 3546 sc.cf = cf; |
3539 sc.lengths = &lcf->root_lengths; | 3547 sc.source = &lcf->root; |
3540 sc.values = &lcf->root_values; | 3548 sc.lengths = &lcf->root_lengths; |
3541 sc.variables = n; | 3549 sc.values = &lcf->root_values; |
3542 sc.complete_lengths = 1; | 3550 sc.variables = n; |
3543 sc.complete_values = 1; | 3551 sc.complete_lengths = 1; |
3544 | 3552 sc.complete_values = 1; |
3545 if (ngx_http_script_compile(&sc) != NGX_OK) { | 3553 |
3554 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
3555 return NGX_CONF_ERROR; | |
3556 } | |
3557 } | |
3558 | |
3559 #if (NGX_PCRE) | |
3560 | |
3561 if (alias && lcf->regex | |
3562 && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0)) | |
3563 { | |
3564 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3565 "the \"alias\" directive must use captures " | |
3566 "inside location given by regular expression"); | |
3567 | |
3546 return NGX_CONF_ERROR; | 3568 return NGX_CONF_ERROR; |
3547 } | 3569 } |
3570 | |
3571 #endif | |
3548 | 3572 |
3549 return NGX_CONF_OK; | 3573 return NGX_CONF_OK; |
3550 } | 3574 } |
3551 | 3575 |
3552 | 3576 |