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