comparison src/http/ngx_http_core_module.c @ 546:e19e5f542878 NGINX_0_8_25

nginx 0.8.25 *) Change: now no message is written in an error log if a variable is not found by $r->variable() method. *) Feature: the ngx_http_degradation_module. *) Feature: regular expression named captures. *) Feature: now URI part is not required a "proxy_pass" directive if variables are used. *) Feature: now the "msie_padding" directive works for Chrome too. *) Bugfix: a segmentation fault occurred in a worker process on low memory condition; the bug had appeared in 0.8.18. *) Bugfix: nginx sent gzipped responses to clients those do not support gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared in 0.8.16.
author Igor Sysoev <http://sysoev.ru>
date Mon, 16 Nov 2009 00:00:00 +0300
parents c04fa65fe604
children ab7d265273ed
comparison
equal deleted inserted replaced
545:91e4b06e1a01 546:e19e5f542878
810 if (r->unparsed_uri.len) { 810 if (r->unparsed_uri.len) {
811 r->valid_unparsed_uri = 1; 811 r->valid_unparsed_uri = 1;
812 } 812 }
813 813
814 r->valid_location = 1; 814 r->valid_location = 1;
815 r->gzip = 0; 815 #if (NGX_HTTP_GZIP)
816 r->gzip_tested = 0;
817 r->gzip_ok = 0;
818 r->gzip_vary = 0;
819 #endif
816 820
817 r->write_event_handler = ngx_http_core_run_phases; 821 r->write_event_handler = ngx_http_core_run_phases;
818 ngx_http_core_run_phases(r); 822 ngx_http_core_run_phases(r);
819 } 823 }
820 824
1414 ngx_http_core_find_location(ngx_http_request_t *r) 1418 ngx_http_core_find_location(ngx_http_request_t *r)
1415 { 1419 {
1416 ngx_int_t rc; 1420 ngx_int_t rc;
1417 ngx_http_core_loc_conf_t *pclcf; 1421 ngx_http_core_loc_conf_t *pclcf;
1418 #if (NGX_PCRE) 1422 #if (NGX_PCRE)
1419 ngx_int_t n, len; 1423 ngx_int_t n;
1420 ngx_uint_t noregex; 1424 ngx_uint_t noregex;
1421 ngx_http_core_loc_conf_t *clcf, **clcfp; 1425 ngx_http_core_loc_conf_t *clcf, **clcfp;
1422 1426
1423 noregex = 0; 1427 noregex = 0;
1424 #endif 1428 #endif
1448 1452
1449 #if (NGX_PCRE) 1453 #if (NGX_PCRE)
1450 1454
1451 if (noregex == 0 && pclcf->regex_locations) { 1455 if (noregex == 0 && pclcf->regex_locations) {
1452 1456
1453 len = 0;
1454
1455 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { 1457 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
1456 1458
1457 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1459 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1458 "test location: ~ \"%V\"", &(*clcfp)->name); 1460 "test location: ~ \"%V\"", &(*clcfp)->name);
1459 1461
1460 if ((*clcfp)->captures) { 1462 n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
1461 1463
1462 len = (NGX_HTTP_MAX_CAPTURES + 1) * 3; 1464 if (n == NGX_OK) {
1463 1465 r->loc_conf = (*clcfp)->loc_conf;
1464 if (r->captures == NULL) { 1466
1465 r->captures = ngx_palloc(r->pool, len * sizeof(int)); 1467 /* look up nested locations */
1466 if (r->captures == NULL) { 1468
1467 return NGX_ERROR; 1469 rc = ngx_http_core_find_location(r);
1468 } 1470
1469 } 1471 return (rc == NGX_ERROR) ? rc : NGX_OK;
1470 } 1472 }
1471 1473
1472 n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len); 1474 if (n == NGX_DECLINED) {
1473
1474 if (n == NGX_REGEX_NO_MATCHED) {
1475 continue; 1475 continue;
1476 } 1476 }
1477 1477
1478 if (n < 0) { 1478 return NGX_ERROR;
1479 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1480 ngx_regex_exec_n
1481 " failed: %d on \"%V\" using \"%V\"",
1482 n, &r->uri, &(*clcfp)->name);
1483 return NGX_ERROR;
1484 }
1485
1486 /* match */
1487
1488 r->loc_conf = (*clcfp)->loc_conf;
1489
1490 r->ncaptures = len;
1491 r->captures_data = r->uri.data;
1492
1493 /* look up nested locations */
1494
1495 rc = ngx_http_core_find_location(r);
1496
1497 return (rc == NGX_ERROR) ? rc : NGX_OK;
1498 } 1479 }
1499 } 1480 }
1500 #endif 1481 #endif
1501 1482
1502 return rc; 1483 return rc;
1772 } else { 1753 } else {
1773 1754
1774 #if (NGX_PCRE) 1755 #if (NGX_PCRE)
1775 ngx_uint_t captures; 1756 ngx_uint_t captures;
1776 1757
1777 captures = alias && clcf->captures; 1758 captures = alias && clcf->regex;
1778 reserved += captures ? 1 : r->uri.len - alias + 1; 1759 reserved += captures ? 1 : r->uri.len - alias + 1;
1779 #else 1760 #else
1780 reserved += r->uri.len - alias + 1; 1761 reserved += r->uri.len - alias + 1;
1781 #endif 1762 #endif
1782 1763
1889 ngx_uint_t p; 1870 ngx_uint_t p;
1890 ngx_array_t *cc; 1871 ngx_array_t *cc;
1891 ngx_table_elt_t *e, *d; 1872 ngx_table_elt_t *e, *d;
1892 ngx_http_core_loc_conf_t *clcf; 1873 ngx_http_core_loc_conf_t *clcf;
1893 1874
1894 if (r->gzip == 1) { 1875 r->gzip_tested = 1;
1895 return NGX_OK;
1896 }
1897
1898 if (r->gzip == 2) {
1899 return NGX_DECLINED;
1900 }
1901
1902 r->gzip = 2;
1903 1876
1904 if (r != r->main 1877 if (r != r->main
1905 || r->headers_in.accept_encoding == NULL 1878 || r->headers_in.accept_encoding == NULL
1906 || ngx_strcasestrn(r->headers_in.accept_encoding->value.data, 1879 || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
1907 "gzip", 4 - 1) 1880 "gzip", 4 - 1)
2032 } 2005 }
2033 } 2006 }
2034 2007
2035 #endif 2008 #endif
2036 2009
2037 r->gzip = 1; 2010 r->gzip_ok = 1;
2038 2011
2039 return NGX_OK; 2012 return NGX_OK;
2040 } 2013 }
2041 2014
2042 #endif 2015 #endif
2598 static ngx_int_t 2571 static ngx_int_t
2599 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,
2600 ngx_str_t *regex, ngx_uint_t caseless) 2573 ngx_str_t *regex, ngx_uint_t caseless)
2601 { 2574 {
2602 #if (NGX_PCRE) 2575 #if (NGX_PCRE)
2603 ngx_str_t err; 2576 ngx_regex_compile_t rc;
2604 u_char errstr[NGX_MAX_CONF_ERRSTR]; 2577 u_char errstr[NGX_MAX_CONF_ERRSTR];
2605 2578
2606 err.len = NGX_MAX_CONF_ERRSTR; 2579 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
2607 err.data = errstr; 2580
2581 rc.pattern = *regex;
2582 rc.err.len = NGX_MAX_CONF_ERRSTR;
2583 rc.err.data = errstr;
2608 2584
2609 #if (NGX_HAVE_CASELESS_FILESYSTEM) 2585 #if (NGX_HAVE_CASELESS_FILESYSTEM)
2610 caseless = 1; 2586 rc.options = NGX_REGEX_CASELESS;
2611 #endif 2587 #endif
2612 2588
2613 clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0, 2589 clcf->regex = ngx_http_regex_compile(cf, &rc);
2614 cf->pool, &err);
2615
2616 if (clcf->regex == NULL) { 2590 if (clcf->regex == NULL) {
2617 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
2618 return NGX_ERROR; 2591 return NGX_ERROR;
2619 } 2592 }
2620 2593
2621 clcf->name = *regex; 2594 clcf->name = *regex;
2622 clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0);
2623 2595
2624 return NGX_OK; 2596 return NGX_OK;
2625 2597
2626 #else 2598 #else
2627 2599
2635 2607
2636 2608
2637 static char * 2609 static char *
2638 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 2610 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2639 { 2611 {
2640 ngx_http_core_loc_conf_t *lcf = conf; 2612 ngx_http_core_loc_conf_t *clcf = conf;
2641 2613
2642 char *rv; 2614 char *rv;
2643 ngx_conf_t save; 2615 ngx_conf_t save;
2644 2616
2645 if (lcf->types == NULL) { 2617 if (clcf->types == NULL) {
2646 lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t)); 2618 clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
2647 if (lcf->types == NULL) { 2619 if (clcf->types == NULL) {
2648 return NGX_CONF_ERROR; 2620 return NGX_CONF_ERROR;
2649 } 2621 }
2650 } 2622 }
2651 2623
2652 save = *cf; 2624 save = *cf;
2662 2634
2663 2635
2664 static char * 2636 static char *
2665 ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) 2637 ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
2666 { 2638 {
2667 ngx_http_core_loc_conf_t *lcf = conf; 2639 ngx_http_core_loc_conf_t *clcf = conf;
2668 2640
2669 ngx_str_t *value, *content_type, *old, file; 2641 ngx_str_t *value, *content_type, *old, file;
2670 ngx_uint_t i, n, hash; 2642 ngx_uint_t i, n, hash;
2671 ngx_hash_key_t *type; 2643 ngx_hash_key_t *type;
2672 2644
2693 2665
2694 for (i = 1; i < cf->args->nelts; i++) { 2666 for (i = 1; i < cf->args->nelts; i++) {
2695 2667
2696 hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len); 2668 hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
2697 2669
2698 type = lcf->types->elts; 2670 type = clcf->types->elts;
2699 for (n = 0; n < lcf->types->nelts; n++) { 2671 for (n = 0; n < clcf->types->nelts; n++) {
2700 if (ngx_strcmp(value[i].data, type[n].key.data) == 0) { 2672 if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
2701 old = type[n].value; 2673 old = type[n].value;
2702 type[n].value = content_type; 2674 type[n].value = content_type;
2703 2675
2704 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, 2676 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
2709 continue; 2681 continue;
2710 } 2682 }
2711 } 2683 }
2712 2684
2713 2685
2714 type = ngx_array_push(lcf->types); 2686 type = ngx_array_push(clcf->types);
2715 if (type == NULL) { 2687 if (type == NULL) {
2716 return NGX_CONF_ERROR; 2688 return NGX_CONF_ERROR;
2717 } 2689 }
2718 2690
2719 type->key = value[i]; 2691 type->key = value[i];
2914 2886
2915 2887
2916 static void * 2888 static void *
2917 ngx_http_core_create_loc_conf(ngx_conf_t *cf) 2889 ngx_http_core_create_loc_conf(ngx_conf_t *cf)
2918 { 2890 {
2919 ngx_http_core_loc_conf_t *lcf; 2891 ngx_http_core_loc_conf_t *clcf;
2920 2892
2921 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)); 2893 clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
2922 if (lcf == NULL) { 2894 if (clcf == NULL) {
2923 return NULL; 2895 return NULL;
2924 } 2896 }
2925 2897
2926 /* 2898 /*
2927 * set by ngx_pcalloc(): 2899 * set by ngx_pcalloc():
2928 * 2900 *
2929 * lcf->root = { 0, NULL }; 2901 * clcf->root = { 0, NULL };
2930 * lcf->limit_except = 0; 2902 * clcf->limit_except = 0;
2931 * lcf->post_action = { 0, NULL }; 2903 * clcf->post_action = { 0, NULL };
2932 * lcf->types = NULL; 2904 * clcf->types = NULL;
2933 * lcf->default_type = { 0, NULL }; 2905 * clcf->default_type = { 0, NULL };
2934 * lcf->error_log = NULL; 2906 * clcf->error_log = NULL;
2935 * lcf->error_pages = NULL; 2907 * clcf->error_pages = NULL;
2936 * lcf->try_files = NULL; 2908 * clcf->try_files = NULL;
2937 * lcf->client_body_path = NULL; 2909 * clcf->client_body_path = NULL;
2938 * lcf->regex = NULL; 2910 * clcf->regex = NULL;
2939 * lcf->exact_match = 0; 2911 * clcf->exact_match = 0;
2940 * lcf->auto_redirect = 0; 2912 * clcf->auto_redirect = 0;
2941 * lcf->alias = 0; 2913 * clcf->alias = 0;
2942 * lcf->gzip_proxied = 0; 2914 * clcf->gzip_proxied = 0;
2943 */ 2915 */
2944 2916
2945 lcf->client_max_body_size = NGX_CONF_UNSET; 2917 clcf->client_max_body_size = NGX_CONF_UNSET;
2946 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; 2918 clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
2947 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; 2919 clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
2948 lcf->satisfy = NGX_CONF_UNSET_UINT; 2920 clcf->satisfy = NGX_CONF_UNSET_UINT;
2949 lcf->if_modified_since = NGX_CONF_UNSET_UINT; 2921 clcf->if_modified_since = NGX_CONF_UNSET_UINT;
2950 lcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; 2922 clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
2951 lcf->client_body_in_single_buffer = NGX_CONF_UNSET; 2923 clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
2952 lcf->internal = NGX_CONF_UNSET; 2924 clcf->internal = NGX_CONF_UNSET;
2953 lcf->sendfile = NGX_CONF_UNSET; 2925 clcf->sendfile = NGX_CONF_UNSET;
2954 lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; 2926 clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
2955 #if (NGX_HAVE_FILE_AIO) 2927 #if (NGX_HAVE_FILE_AIO)
2956 lcf->aio = NGX_CONF_UNSET; 2928 clcf->aio = NGX_CONF_UNSET;
2957 #endif 2929 #endif
2958 lcf->read_ahead = NGX_CONF_UNSET_SIZE; 2930 clcf->read_ahead = NGX_CONF_UNSET_SIZE;
2959 lcf->directio = NGX_CONF_UNSET; 2931 clcf->directio = NGX_CONF_UNSET;
2960 lcf->directio_alignment = NGX_CONF_UNSET; 2932 clcf->directio_alignment = NGX_CONF_UNSET;
2961 lcf->tcp_nopush = NGX_CONF_UNSET; 2933 clcf->tcp_nopush = NGX_CONF_UNSET;
2962 lcf->tcp_nodelay = NGX_CONF_UNSET; 2934 clcf->tcp_nodelay = NGX_CONF_UNSET;
2963 lcf->send_timeout = NGX_CONF_UNSET_MSEC; 2935 clcf->send_timeout = NGX_CONF_UNSET_MSEC;
2964 lcf->send_lowat = NGX_CONF_UNSET_SIZE; 2936 clcf->send_lowat = NGX_CONF_UNSET_SIZE;
2965 lcf->postpone_output = NGX_CONF_UNSET_SIZE; 2937 clcf->postpone_output = NGX_CONF_UNSET_SIZE;
2966 lcf->limit_rate = NGX_CONF_UNSET_SIZE; 2938 clcf->limit_rate = NGX_CONF_UNSET_SIZE;
2967 lcf->limit_rate_after = NGX_CONF_UNSET_SIZE; 2939 clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
2968 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC; 2940 clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
2969 lcf->keepalive_header = NGX_CONF_UNSET; 2941 clcf->keepalive_header = NGX_CONF_UNSET;
2970 lcf->keepalive_requests = NGX_CONF_UNSET_UINT; 2942 clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
2971 lcf->lingering_time = NGX_CONF_UNSET_MSEC; 2943 clcf->lingering_time = NGX_CONF_UNSET_MSEC;
2972 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC; 2944 clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
2973 lcf->resolver_timeout = NGX_CONF_UNSET_MSEC; 2945 clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
2974 lcf->reset_timedout_connection = NGX_CONF_UNSET; 2946 clcf->reset_timedout_connection = NGX_CONF_UNSET;
2975 lcf->server_name_in_redirect = NGX_CONF_UNSET; 2947 clcf->server_name_in_redirect = NGX_CONF_UNSET;
2976 lcf->port_in_redirect = NGX_CONF_UNSET; 2948 clcf->port_in_redirect = NGX_CONF_UNSET;
2977 lcf->msie_padding = NGX_CONF_UNSET; 2949 clcf->msie_padding = NGX_CONF_UNSET;
2978 lcf->msie_refresh = NGX_CONF_UNSET; 2950 clcf->msie_refresh = NGX_CONF_UNSET;
2979 lcf->log_not_found = NGX_CONF_UNSET; 2951 clcf->log_not_found = NGX_CONF_UNSET;
2980 lcf->log_subrequest = NGX_CONF_UNSET; 2952 clcf->log_subrequest = NGX_CONF_UNSET;
2981 lcf->recursive_error_pages = NGX_CONF_UNSET; 2953 clcf->recursive_error_pages = NGX_CONF_UNSET;
2982 lcf->server_tokens = NGX_CONF_UNSET; 2954 clcf->server_tokens = NGX_CONF_UNSET;
2983 lcf->types_hash_max_size = NGX_CONF_UNSET_UINT; 2955 clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2984 lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; 2956 clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
2985 2957
2986 lcf->open_file_cache = NGX_CONF_UNSET_PTR; 2958 clcf->open_file_cache = NGX_CONF_UNSET_PTR;
2987 lcf->open_file_cache_valid = NGX_CONF_UNSET; 2959 clcf->open_file_cache_valid = NGX_CONF_UNSET;
2988 lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT; 2960 clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
2989 lcf->open_file_cache_errors = NGX_CONF_UNSET; 2961 clcf->open_file_cache_errors = NGX_CONF_UNSET;
2990 lcf->open_file_cache_events = NGX_CONF_UNSET; 2962 clcf->open_file_cache_events = NGX_CONF_UNSET;
2991 2963
2992 #if (NGX_HTTP_GZIP) 2964 #if (NGX_HTTP_GZIP)
2993 lcf->gzip_vary = NGX_CONF_UNSET; 2965 clcf->gzip_vary = NGX_CONF_UNSET;
2994 lcf->gzip_http_version = NGX_CONF_UNSET_UINT; 2966 clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
2995 #if (NGX_PCRE) 2967 #if (NGX_PCRE)
2996 lcf->gzip_disable = NGX_CONF_UNSET_PTR; 2968 clcf->gzip_disable = NGX_CONF_UNSET_PTR;
2997 lcf->gzip_disable_msie6 = 3; 2969 clcf->gzip_disable_msie6 = 3;
2998 #endif 2970 #endif
2999 #endif 2971 #endif
3000 2972
3001 return lcf; 2973 return clcf;
3002 } 2974 }
3003 2975
3004 2976
3005 static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html"); 2977 static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
3006 static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif"); 2978 static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
3537 continue; 3509 continue;
3538 } 3510 }
3539 3511
3540 #if (NGX_PCRE) 3512 #if (NGX_PCRE)
3541 { 3513 {
3542 ngx_str_t err; 3514 ngx_regex_compile_t rc;
3543 u_char errstr[NGX_MAX_CONF_ERRSTR]; 3515 u_char errstr[NGX_MAX_CONF_ERRSTR];
3544 3516
3545 if (value[i].len == 1) { 3517 if (value[i].len == 1) {
3546 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3518 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3547 "empty regex in server name \"%V\"", &value[i]); 3519 "empty regex in server name \"%V\"", &value[i]);
3548 return NGX_CONF_ERROR; 3520 return NGX_CONF_ERROR;
3549 } 3521 }
3550 3522
3551 err.len = NGX_MAX_CONF_ERRSTR;
3552 err.data = errstr;
3553
3554 value[i].len--; 3523 value[i].len--;
3555 value[i].data++; 3524 value[i].data++;
3556 3525
3557 sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err); 3526 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
3558 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);
3559 if (sn->regex == NULL) { 3533 if (sn->regex == NULL) {
3560 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
3561 return NGX_CONF_ERROR; 3534 return NGX_CONF_ERROR;
3562 } 3535 }
3563 3536
3564 sn->name = value[i]; 3537 sn->name = value[i];
3565 cscf->captures = (ngx_regex_capture_count(sn->regex) > 0); 3538 cscf->captures = (rc.captures > 0);
3566 } 3539 }
3567 #else 3540 #else
3568 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3541 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3569 "the using of the regex \"%V\" " 3542 "the using of the regex \"%V\" "
3570 "requires PCRE library", &value[i]); 3543 "requires PCRE library", &value[i]);
3578 3551
3579 3552
3580 static char * 3553 static char *
3581 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3554 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3582 { 3555 {
3583 ngx_http_core_loc_conf_t *lcf = conf; 3556 ngx_http_core_loc_conf_t *clcf = conf;
3584 3557
3585 ngx_str_t *value; 3558 ngx_str_t *value;
3586 ngx_uint_t alias, n; 3559 ngx_uint_t alias, n;
3587 ngx_http_script_compile_t sc; 3560 ngx_http_script_compile_t sc;
3588 3561
3589 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; 3562 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
3590 3563
3591 if (lcf->root.data) { 3564 if (clcf->root.data) {
3592 3565
3593 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */ 3566 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
3594 3567
3595 if ((ngx_uint_t) lcf->alias == alias) { 3568 if ((ngx_uint_t) clcf->alias == alias) {
3596 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3569 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3597 "\"%V\" directive is duplicate", 3570 "\"%V\" directive is duplicate",
3598 &cmd->name); 3571 &cmd->name);
3599 } else { 3572 } else {
3600 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3573 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3601 "\"%V\" directive is duplicate, " 3574 "\"%V\" directive is duplicate, "
3602 "\"%s\" directive is specified before", 3575 "\"%s\" directive is specified before",
3603 &cmd->name, lcf->alias ? "alias" : "root"); 3576 &cmd->name, clcf->alias ? "alias" : "root");
3604 } 3577 }
3605 3578
3606 return NGX_CONF_ERROR; 3579 return NGX_CONF_ERROR;
3607 } 3580 }
3608 3581
3609 if (lcf->named && alias) { 3582 if (clcf->named && alias) {
3610 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3583 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3611 "the \"alias\" directive may not be used " 3584 "the \"alias\" directive may not be used "
3612 "inside named location"); 3585 "inside named location");
3613 3586
3614 return NGX_CONF_ERROR; 3587 return NGX_CONF_ERROR;
3636 &cmd->name); 3609 &cmd->name);
3637 3610
3638 return NGX_CONF_ERROR; 3611 return NGX_CONF_ERROR;
3639 } 3612 }
3640 3613
3641 lcf->alias = alias; 3614 clcf->alias = alias;
3642 lcf->root = value[1]; 3615 clcf->root = value[1];
3643 3616
3644 if (!alias && lcf->root.data[lcf->root.len - 1] == '/') { 3617 if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
3645 lcf->root.len--; 3618 clcf->root.len--;
3646 } 3619 }
3647 3620
3648 if (lcf->root.data[0] != '$') { 3621 if (clcf->root.data[0] != '$') {
3649 if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) { 3622 if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
3650 return NGX_CONF_ERROR; 3623 return NGX_CONF_ERROR;
3651 } 3624 }
3652 } 3625 }
3653 3626
3654 n = ngx_http_script_variables_count(&lcf->root); 3627 n = ngx_http_script_variables_count(&clcf->root);
3655 3628
3656 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); 3629 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3657 3630
3658 if (n) { 3631 if (n) {
3659 sc.cf = cf; 3632 sc.cf = cf;
3660 sc.source = &lcf->root; 3633 sc.source = &clcf->root;
3661 sc.lengths = &lcf->root_lengths; 3634 sc.lengths = &clcf->root_lengths;
3662 sc.values = &lcf->root_values; 3635 sc.values = &clcf->root_values;
3663 sc.variables = n; 3636 sc.variables = n;
3664 sc.complete_lengths = 1; 3637 sc.complete_lengths = 1;
3665 sc.complete_values = 1; 3638 sc.complete_values = 1;
3666 3639
3667 if (ngx_http_script_compile(&sc) != NGX_OK) { 3640 if (ngx_http_script_compile(&sc) != NGX_OK) {
3668 return NGX_CONF_ERROR; 3641 return NGX_CONF_ERROR;
3669 } 3642 }
3670 } 3643 }
3671
3672 #if (NGX_PCRE)
3673
3674 if (alias && lcf->regex
3675 && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0))
3676 {
3677 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3678 "the \"alias\" directive must use captures "
3679 "inside location given by regular expression");
3680
3681 return NGX_CONF_ERROR;
3682 }
3683
3684 #endif
3685 3644
3686 return NGX_CONF_OK; 3645 return NGX_CONF_OK;
3687 } 3646 }
3688 3647
3689 3648
3832 3791
3833 3792
3834 static char * 3793 static char *
3835 ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3794 ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3836 { 3795 {
3837 ngx_http_core_loc_conf_t *lcf = conf; 3796 ngx_http_core_loc_conf_t *clcf = conf;
3838 3797
3839 u_char *p; 3798 u_char *p;
3840 ngx_int_t overwrite; 3799 ngx_int_t overwrite;
3841 ngx_str_t *value, uri, args; 3800 ngx_str_t *value, uri, args;
3842 ngx_uint_t i, n; 3801 ngx_uint_t i, n;
3843 ngx_http_err_page_t *err; 3802 ngx_http_err_page_t *err;
3844 ngx_http_complex_value_t cv; 3803 ngx_http_complex_value_t cv;
3845 ngx_http_compile_complex_value_t ccv; 3804 ngx_http_compile_complex_value_t ccv;
3846 3805
3847 if (lcf->error_pages == NULL) { 3806 if (clcf->error_pages == NULL) {
3848 lcf->error_pages = ngx_array_create(cf->pool, 4, 3807 clcf->error_pages = ngx_array_create(cf->pool, 4,
3849 sizeof(ngx_http_err_page_t)); 3808 sizeof(ngx_http_err_page_t));
3850 if (lcf->error_pages == NULL) { 3809 if (clcf->error_pages == NULL) {
3851 return NGX_CONF_ERROR; 3810 return NGX_CONF_ERROR;
3852 } 3811 }
3853 } 3812 }
3854 3813
3855 value = cf->args->elts; 3814 value = cf->args->elts;
3909 args.data = p; 3868 args.data = p;
3910 } 3869 }
3911 } 3870 }
3912 3871
3913 for (i = 1; i < cf->args->nelts - n; i++) { 3872 for (i = 1; i < cf->args->nelts - n; i++) {
3914 err = ngx_array_push(lcf->error_pages); 3873 err = ngx_array_push(clcf->error_pages);
3915 if (err == NULL) { 3874 if (err == NULL) {
3916 return NGX_CONF_ERROR; 3875 return NGX_CONF_ERROR;
3917 } 3876 }
3918 3877
3919 err->status = ngx_atoi(value[i].data, value[i].len); 3878 err->status = ngx_atoi(value[i].data, value[i].len);
4037 3996
4038 3997
4039 static char * 3998 static char *
4040 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3999 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4041 { 4000 {
4042 ngx_http_core_loc_conf_t *lcf = conf; 4001 ngx_http_core_loc_conf_t *clcf = conf;
4043 4002
4044 time_t inactive; 4003 time_t inactive;
4045 ngx_str_t *value, s; 4004 ngx_str_t *value, s;
4046 ngx_int_t max; 4005 ngx_int_t max;
4047 ngx_uint_t i; 4006 ngx_uint_t i;
4048 4007
4049 if (lcf->open_file_cache != NGX_CONF_UNSET_PTR) { 4008 if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
4050 return "is duplicate"; 4009 return "is duplicate";
4051 } 4010 }
4052 4011
4053 value = cf->args->elts; 4012 value = cf->args->elts;
4054 4013
4080 continue; 4039 continue;
4081 } 4040 }
4082 4041
4083 if (ngx_strcmp(value[i].data, "off") == 0) { 4042 if (ngx_strcmp(value[i].data, "off") == 0) {
4084 4043
4085 lcf->open_file_cache = NULL; 4044 clcf->open_file_cache = NULL;
4086 4045
4087 continue; 4046 continue;
4088 } 4047 }
4089 4048
4090 failed: 4049 failed:
4093 "invalid \"open_file_cache\" parameter \"%V\"", 4052 "invalid \"open_file_cache\" parameter \"%V\"",
4094 &value[i]); 4053 &value[i]);
4095 return NGX_CONF_ERROR; 4054 return NGX_CONF_ERROR;
4096 } 4055 }
4097 4056
4098 if (lcf->open_file_cache == NULL) { 4057 if (clcf->open_file_cache == NULL) {
4099 return NGX_CONF_OK; 4058 return NGX_CONF_OK;
4100 } 4059 }
4101 4060
4102 if (max == 0) { 4061 if (max == 0) {
4103 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 4062 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4104 "\"open_file_cache\" must have \"max\" parameter"); 4063 "\"open_file_cache\" must have \"max\" parameter");
4105 return NGX_CONF_ERROR; 4064 return NGX_CONF_ERROR;
4106 } 4065 }
4107 4066
4108 lcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive); 4067 clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
4109 if (lcf->open_file_cache) { 4068 if (clcf->open_file_cache) {
4110 return NGX_CONF_OK; 4069 return NGX_CONF_OK;
4111 } 4070 }
4112 4071
4113 return NGX_CONF_ERROR; 4072 return NGX_CONF_ERROR;
4114 } 4073 }
4115 4074
4116 4075
4117 static char * 4076 static char *
4118 ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 4077 ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4119 { 4078 {
4120 ngx_http_core_loc_conf_t *lcf = conf; 4079 ngx_http_core_loc_conf_t *clcf = conf;
4121 4080
4122 ngx_str_t *value; 4081 ngx_str_t *value;
4123 4082
4124 if (lcf->error_log) { 4083 if (clcf->error_log) {
4125 return "is duplicate"; 4084 return "is duplicate";
4126 } 4085 }
4127 4086
4128 value = cf->args->elts; 4087 value = cf->args->elts;
4129 4088
4130 lcf->error_log = ngx_log_create(cf->cycle, &value[1]); 4089 clcf->error_log = ngx_log_create(cf->cycle, &value[1]);
4131 if (lcf->error_log == NULL) { 4090 if (clcf->error_log == NULL) {
4132 return NGX_CONF_ERROR; 4091 return NGX_CONF_ERROR;
4133 } 4092 }
4134 4093
4135 if (cf->args->nelts == 2) { 4094 if (cf->args->nelts == 2) {
4136 lcf->error_log->log_level = NGX_LOG_ERR; 4095 clcf->error_log->log_level = NGX_LOG_ERR;
4137 return NGX_CONF_OK; 4096 return NGX_CONF_OK;
4138 } 4097 }
4139 4098
4140 return ngx_log_set_levels(cf, lcf->error_log); 4099 return ngx_log_set_levels(cf, clcf->error_log);
4141 } 4100 }
4142 4101
4143 4102
4144 static char * 4103 static char *
4145 ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 4104 ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4146 { 4105 {
4147 ngx_http_core_loc_conf_t *lcf = conf; 4106 ngx_http_core_loc_conf_t *clcf = conf;
4148 4107
4149 ngx_str_t *value; 4108 ngx_str_t *value;
4150 4109
4151 if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) { 4110 if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
4152 return "is duplicate"; 4111 return "is duplicate";
4153 } 4112 }
4154 4113
4155 value = cf->args->elts; 4114 value = cf->args->elts;
4156 4115
4157 lcf->keepalive_timeout = ngx_parse_time(&value[1], 0); 4116 clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
4158 4117
4159 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) { 4118 if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
4160 return "invalid value"; 4119 return "invalid value";
4161 } 4120 }
4162 4121
4163 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { 4122 if (clcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
4164 return "value must be less than 597 hours"; 4123 return "value must be less than 597 hours";
4165 } 4124 }
4166 4125
4167 if (cf->args->nelts == 2) { 4126 if (cf->args->nelts == 2) {
4168 return NGX_CONF_OK; 4127 return NGX_CONF_OK;
4169 } 4128 }
4170 4129
4171 lcf->keepalive_header = ngx_parse_time(&value[2], 1); 4130 clcf->keepalive_header = ngx_parse_time(&value[2], 1);
4172 4131
4173 if (lcf->keepalive_header == NGX_ERROR) { 4132 if (clcf->keepalive_header == NGX_ERROR) {
4174 return "invalid value"; 4133 return "invalid value";
4175 } 4134 }
4176 4135
4177 if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) { 4136 if (clcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
4178 return "value must be less than 68 years"; 4137 return "value must be less than 68 years";
4179 } 4138 }
4180 4139
4181 return NGX_CONF_OK; 4140 return NGX_CONF_OK;
4182 } 4141 }
4183 4142
4184 4143
4185 static char * 4144 static char *
4186 ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 4145 ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4187 { 4146 {
4188 ngx_http_core_loc_conf_t *lcf = conf; 4147 ngx_http_core_loc_conf_t *clcf = conf;
4189 4148
4190 if (lcf->internal != NGX_CONF_UNSET) { 4149 if (clcf->internal != NGX_CONF_UNSET) {
4191 return "is duplicate"; 4150 return "is duplicate";
4192 } 4151 }
4193 4152
4194 lcf->internal = 1; 4153 clcf->internal = 1;
4195 4154
4196 return NGX_CONF_OK; 4155 return NGX_CONF_OK;
4197 } 4156 }
4198 4157
4199 4158
4237 { 4196 {
4238 ngx_http_core_loc_conf_t *clcf = conf; 4197 ngx_http_core_loc_conf_t *clcf = conf;
4239 4198
4240 #if (NGX_PCRE) 4199 #if (NGX_PCRE)
4241 4200
4242 ngx_str_t err, *value; 4201 ngx_str_t *value;
4243 ngx_uint_t i; 4202 ngx_uint_t i;
4244 ngx_regex_elt_t *re; 4203 ngx_regex_elt_t *re;
4245 u_char errstr[NGX_MAX_CONF_ERRSTR]; 4204 ngx_regex_compile_t rc;
4205 u_char errstr[NGX_MAX_CONF_ERRSTR];
4246 4206
4247 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) { 4207 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
4248 clcf->gzip_disable = ngx_array_create(cf->pool, 2, 4208 clcf->gzip_disable = ngx_array_create(cf->pool, 2,
4249 sizeof(ngx_regex_elt_t)); 4209 sizeof(ngx_regex_elt_t));
4250 if (clcf->gzip_disable == NULL) { 4210 if (clcf->gzip_disable == NULL) {
4252 } 4212 }
4253 } 4213 }
4254 4214
4255 value = cf->args->elts; 4215 value = cf->args->elts;
4256 4216
4257 err.len = NGX_MAX_CONF_ERRSTR; 4217 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
4258 err.data = errstr; 4218
4219 rc.pool = cf->pool;
4220 rc.err.len = NGX_MAX_CONF_ERRSTR;
4221 rc.err.data = errstr;
4259 4222
4260 for (i = 1; i < cf->args->nelts; i++) { 4223 for (i = 1; i < cf->args->nelts; i++) {
4261 4224
4262 if (ngx_strcmp(value[1].data, "msie6") == 0) { 4225 if (ngx_strcmp(value[1].data, "msie6") == 0) {
4263 clcf->gzip_disable_msie6 = 1; 4226 clcf->gzip_disable_msie6 = 1;
4267 re = ngx_array_push(clcf->gzip_disable); 4230 re = ngx_array_push(clcf->gzip_disable);
4268 if (re == NULL) { 4231 if (re == NULL) {
4269 return NGX_CONF_ERROR; 4232 return NGX_CONF_ERROR;
4270 } 4233 }
4271 4234
4272 re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool, 4235 rc.pattern = value[1];
4273 &err); 4236 rc.options = NGX_REGEX_CASELESS;
4274 4237
4275 if (re->regex == NULL) { 4238 if (ngx_regex_compile(&rc) != NGX_OK) {
4276 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);
4277 return NGX_CONF_ERROR; 4240 return NGX_CONF_ERROR;
4278 } 4241 }
4279 4242
4243 re->regex = rc.regex;
4280 re->name = value[i].data; 4244 re->name = value[i].data;
4281 } 4245 }
4282 4246
4283 return NGX_CONF_OK; 4247 return NGX_CONF_OK;
4284 4248