Index: src/http/ngx_http_core_module.c =================================================================== --- src/http/ngx_http_core_module.c (revision 2637) +++ src/http/ngx_http_core_module.c (working copy) @@ -1420,7 +1420,7 @@ ngx_int_t rc; ngx_http_core_loc_conf_t *pclcf; #if (NGX_PCRE) - ngx_int_t n, len; + ngx_int_t n; ngx_uint_t noregex; ngx_http_core_loc_conf_t *clcf, **clcfp; @@ -1454,36 +1454,18 @@ if (noregex == 0 && pclcf->regex_locations) { - len = 0; - for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "test location: ~ \"%V\"", &(*clcfp)->name); - if ((*clcfp)->captures) { + n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri); - len = (NGX_HTTP_MAX_CAPTURES + 1) * 3; - - if (r->captures == NULL) { - r->captures = ngx_palloc(r->pool, len * sizeof(int)); - if (r->captures == NULL) { - return NGX_ERROR; - } - } - } - - n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len); - - if (n == NGX_REGEX_NO_MATCHED) { + if (n == NGX_DECLINED) { continue; } - if (n < 0) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n - " failed: %d on \"%V\" using \"%V\"", - n, &r->uri, &(*clcfp)->name); + if (n == NGX_ERROR) { return NGX_ERROR; } @@ -1491,9 +1473,6 @@ r->loc_conf = (*clcfp)->loc_conf; - r->ncaptures = len; - r->captures_data = r->uri.data; - /* look up nested locations */ rc = ngx_http_core_find_location(r); @@ -1778,7 +1757,7 @@ #if (NGX_PCRE) ngx_uint_t captures; - captures = alias && clcf->captures; + captures = alias && clcf->regex; reserved += captures ? 1 : r->uri.len - alias + 1; #else reserved += r->uri.len - alias + 1; @@ -2596,26 +2575,25 @@ ngx_str_t *regex, ngx_uint_t caseless) { #if (NGX_PCRE) - ngx_str_t err; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); + rc.pattern = *regex; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + #if (NGX_HAVE_CASELESS_FILESYSTEM) - caseless = 1; + rc.options = NGX_REGEX_CASELESS; #endif - clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0, - cf->pool, &err); - + clcf->regex = ngx_http_regex_compile(cf, &rc); if (clcf->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); return NGX_ERROR; } clcf->name = *regex; - clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0); return NGX_OK; @@ -2633,14 +2611,14 @@ static char * ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; char *rv; ngx_conf_t save; - if (lcf->types == NULL) { - lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t)); - if (lcf->types == NULL) { + if (clcf->types == NULL) { + clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t)); + if (clcf->types == NULL) { return NGX_CONF_ERROR; } } @@ -2660,7 +2638,7 @@ static char * ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; ngx_str_t *value, *content_type, *old, file; ngx_uint_t i, n, hash; @@ -2691,8 +2669,8 @@ hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len); - type = lcf->types->elts; - for (n = 0; n < lcf->types->nelts; n++) { + type = clcf->types->elts; + for (n = 0; n < clcf->types->nelts; n++) { if (ngx_strcmp(value[i].data, type[n].key.data) == 0) { old = type[n].value; type[n].value = content_type; @@ -2707,7 +2685,7 @@ } - type = ngx_array_push(lcf->types); + type = ngx_array_push(clcf->types); if (type == NULL) { return NGX_CONF_ERROR; } @@ -2912,89 +2890,89 @@ static void * ngx_http_core_create_loc_conf(ngx_conf_t *cf) { - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; - lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)); - if (lcf == NULL) { + clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t)); + if (clcf == NULL) { return NULL; } /* * set by ngx_pcalloc(): * - * lcf->root = { 0, NULL }; - * lcf->limit_except = 0; - * lcf->post_action = { 0, NULL }; - * lcf->types = NULL; - * lcf->default_type = { 0, NULL }; - * lcf->error_log = NULL; - * lcf->error_pages = NULL; - * lcf->try_files = NULL; - * lcf->client_body_path = NULL; - * lcf->regex = NULL; - * lcf->exact_match = 0; - * lcf->auto_redirect = 0; - * lcf->alias = 0; - * lcf->gzip_proxied = 0; + * clcf->root = { 0, NULL }; + * clcf->limit_except = 0; + * clcf->post_action = { 0, NULL }; + * clcf->types = NULL; + * clcf->default_type = { 0, NULL }; + * clcf->error_log = NULL; + * clcf->error_pages = NULL; + * clcf->try_files = NULL; + * clcf->client_body_path = NULL; + * clcf->regex = NULL; + * clcf->exact_match = 0; + * clcf->auto_redirect = 0; + * clcf->alias = 0; + * clcf->gzip_proxied = 0; */ - lcf->client_max_body_size = NGX_CONF_UNSET; - lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; - lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; - lcf->satisfy = NGX_CONF_UNSET_UINT; - lcf->if_modified_since = NGX_CONF_UNSET_UINT; - lcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; - lcf->client_body_in_single_buffer = NGX_CONF_UNSET; - lcf->internal = NGX_CONF_UNSET; - lcf->sendfile = NGX_CONF_UNSET; - lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; + clcf->client_max_body_size = NGX_CONF_UNSET; + clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; + clcf->client_body_timeout = NGX_CONF_UNSET_MSEC; + clcf->satisfy = NGX_CONF_UNSET_UINT; + clcf->if_modified_since = NGX_CONF_UNSET_UINT; + clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; + clcf->client_body_in_single_buffer = NGX_CONF_UNSET; + clcf->internal = NGX_CONF_UNSET; + clcf->sendfile = NGX_CONF_UNSET; + clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; #if (NGX_HAVE_FILE_AIO) - lcf->aio = NGX_CONF_UNSET; + clcf->aio = NGX_CONF_UNSET; #endif - lcf->read_ahead = NGX_CONF_UNSET_SIZE; - lcf->directio = NGX_CONF_UNSET; - lcf->directio_alignment = NGX_CONF_UNSET; - lcf->tcp_nopush = NGX_CONF_UNSET; - lcf->tcp_nodelay = NGX_CONF_UNSET; - lcf->send_timeout = NGX_CONF_UNSET_MSEC; - lcf->send_lowat = NGX_CONF_UNSET_SIZE; - lcf->postpone_output = NGX_CONF_UNSET_SIZE; - lcf->limit_rate = NGX_CONF_UNSET_SIZE; - lcf->limit_rate_after = NGX_CONF_UNSET_SIZE; - lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC; - lcf->keepalive_header = NGX_CONF_UNSET; - lcf->keepalive_requests = NGX_CONF_UNSET_UINT; - lcf->lingering_time = NGX_CONF_UNSET_MSEC; - lcf->lingering_timeout = NGX_CONF_UNSET_MSEC; - lcf->resolver_timeout = NGX_CONF_UNSET_MSEC; - lcf->reset_timedout_connection = NGX_CONF_UNSET; - lcf->server_name_in_redirect = NGX_CONF_UNSET; - lcf->port_in_redirect = NGX_CONF_UNSET; - lcf->msie_padding = NGX_CONF_UNSET; - lcf->msie_refresh = NGX_CONF_UNSET; - lcf->log_not_found = NGX_CONF_UNSET; - lcf->log_subrequest = NGX_CONF_UNSET; - lcf->recursive_error_pages = NGX_CONF_UNSET; - lcf->server_tokens = NGX_CONF_UNSET; - lcf->types_hash_max_size = NGX_CONF_UNSET_UINT; - lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; + clcf->read_ahead = NGX_CONF_UNSET_SIZE; + clcf->directio = NGX_CONF_UNSET; + clcf->directio_alignment = NGX_CONF_UNSET; + clcf->tcp_nopush = NGX_CONF_UNSET; + clcf->tcp_nodelay = NGX_CONF_UNSET; + clcf->send_timeout = NGX_CONF_UNSET_MSEC; + clcf->send_lowat = NGX_CONF_UNSET_SIZE; + clcf->postpone_output = NGX_CONF_UNSET_SIZE; + clcf->limit_rate = NGX_CONF_UNSET_SIZE; + clcf->limit_rate_after = NGX_CONF_UNSET_SIZE; + clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC; + clcf->keepalive_header = NGX_CONF_UNSET; + clcf->keepalive_requests = NGX_CONF_UNSET_UINT; + clcf->lingering_time = NGX_CONF_UNSET_MSEC; + clcf->lingering_timeout = NGX_CONF_UNSET_MSEC; + clcf->resolver_timeout = NGX_CONF_UNSET_MSEC; + clcf->reset_timedout_connection = NGX_CONF_UNSET; + clcf->server_name_in_redirect = NGX_CONF_UNSET; + clcf->port_in_redirect = NGX_CONF_UNSET; + clcf->msie_padding = NGX_CONF_UNSET; + clcf->msie_refresh = NGX_CONF_UNSET; + clcf->log_not_found = NGX_CONF_UNSET; + clcf->log_subrequest = NGX_CONF_UNSET; + clcf->recursive_error_pages = NGX_CONF_UNSET; + clcf->server_tokens = NGX_CONF_UNSET; + clcf->types_hash_max_size = NGX_CONF_UNSET_UINT; + clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; - lcf->open_file_cache = NGX_CONF_UNSET_PTR; - lcf->open_file_cache_valid = NGX_CONF_UNSET; - lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT; - lcf->open_file_cache_errors = NGX_CONF_UNSET; - lcf->open_file_cache_events = NGX_CONF_UNSET; + clcf->open_file_cache = NGX_CONF_UNSET_PTR; + clcf->open_file_cache_valid = NGX_CONF_UNSET; + clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT; + clcf->open_file_cache_errors = NGX_CONF_UNSET; + clcf->open_file_cache_events = NGX_CONF_UNSET; #if (NGX_HTTP_GZIP) - lcf->gzip_vary = NGX_CONF_UNSET; - lcf->gzip_http_version = NGX_CONF_UNSET_UINT; + clcf->gzip_vary = NGX_CONF_UNSET; + clcf->gzip_http_version = NGX_CONF_UNSET_UINT; #if (NGX_PCRE) - lcf->gzip_disable = NGX_CONF_UNSET_PTR; - lcf->gzip_disable_msie6 = 3; + clcf->gzip_disable = NGX_CONF_UNSET_PTR; + clcf->gzip_disable_msie6 = 3; #endif #endif - return lcf; + return clcf; } @@ -3535,8 +3513,8 @@ #if (NGX_PCRE) { - ngx_str_t err; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; if (value[i].len == 1) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -3544,21 +3522,22 @@ return NGX_CONF_ERROR; } - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; - value[i].len--; value[i].data++; - sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err); + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); + rc.pattern = value[i]; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + + sn->regex = ngx_http_regex_compile(cf, &rc); if (sn->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); return NGX_CONF_ERROR; } sn->name = value[i]; - cscf->captures = (ngx_regex_capture_count(sn->regex) > 0); + cscf->captures = (rc.captures > 0); } #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -3576,7 +3555,7 @@ static char * ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; ngx_str_t *value; ngx_uint_t alias, n; @@ -3584,11 +3563,11 @@ alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; - if (lcf->root.data) { + if (clcf->root.data) { /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */ - if ((ngx_uint_t) lcf->alias == alias) { + if ((ngx_uint_t) clcf->alias == alias) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" directive is duplicate", &cmd->name); @@ -3596,13 +3575,13 @@ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" directive is duplicate, " "\"%s\" directive is specified before", - &cmd->name, lcf->alias ? "alias" : "root"); + &cmd->name, clcf->alias ? "alias" : "root"); } return NGX_CONF_ERROR; } - if (lcf->named && alias) { + if (clcf->named && alias) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"alias\" directive may not be used " "inside named location"); @@ -3634,28 +3613,28 @@ return NGX_CONF_ERROR; } - lcf->alias = alias; - lcf->root = value[1]; + clcf->alias = alias; + clcf->root = value[1]; - if (!alias && lcf->root.data[lcf->root.len - 1] == '/') { - lcf->root.len--; + if (!alias && clcf->root.data[clcf->root.len - 1] == '/') { + clcf->root.len--; } - if (lcf->root.data[0] != '$') { - if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) { + if (clcf->root.data[0] != '$') { + if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) { return NGX_CONF_ERROR; } } - n = ngx_http_script_variables_count(&lcf->root); + n = ngx_http_script_variables_count(&clcf->root); ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); if (n) { sc.cf = cf; - sc.source = &lcf->root; - sc.lengths = &lcf->root_lengths; - sc.values = &lcf->root_values; + sc.source = &clcf->root; + sc.lengths = &clcf->root_lengths; + sc.values = &clcf->root_values; sc.variables = n; sc.complete_lengths = 1; sc.complete_values = 1; @@ -3665,20 +3644,6 @@ } } -#if (NGX_PCRE) - - if (alias && lcf->regex - && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0)) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the \"alias\" directive must use captures " - "inside location given by regular expression"); - - return NGX_CONF_ERROR; - } - -#endif - return NGX_CONF_OK; } @@ -3830,7 +3795,7 @@ static char * ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; u_char *p; ngx_int_t overwrite; @@ -3840,10 +3805,10 @@ ngx_http_complex_value_t cv; ngx_http_compile_complex_value_t ccv; - if (lcf->error_pages == NULL) { - lcf->error_pages = ngx_array_create(cf->pool, 4, - sizeof(ngx_http_err_page_t)); - if (lcf->error_pages == NULL) { + if (clcf->error_pages == NULL) { + clcf->error_pages = ngx_array_create(cf->pool, 4, + sizeof(ngx_http_err_page_t)); + if (clcf->error_pages == NULL) { return NGX_CONF_ERROR; } } @@ -3907,7 +3872,7 @@ } for (i = 1; i < cf->args->nelts - n; i++) { - err = ngx_array_push(lcf->error_pages); + err = ngx_array_push(clcf->error_pages); if (err == NULL) { return NGX_CONF_ERROR; } @@ -4035,14 +4000,14 @@ static char * ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; time_t inactive; ngx_str_t *value, s; ngx_int_t max; ngx_uint_t i; - if (lcf->open_file_cache != NGX_CONF_UNSET_PTR) { + if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) { return "is duplicate"; } @@ -4078,7 +4043,7 @@ if (ngx_strcmp(value[i].data, "off") == 0) { - lcf->open_file_cache = NULL; + clcf->open_file_cache = NULL; continue; } @@ -4091,7 +4056,7 @@ return NGX_CONF_ERROR; } - if (lcf->open_file_cache == NULL) { + if (clcf->open_file_cache == NULL) { return NGX_CONF_OK; } @@ -4101,8 +4066,8 @@ return NGX_CONF_ERROR; } - lcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive); - if (lcf->open_file_cache) { + clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive); + if (clcf->open_file_cache) { return NGX_CONF_OK; } @@ -4113,50 +4078,50 @@ static char * ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; ngx_str_t *value; - if (lcf->error_log) { + if (clcf->error_log) { return "is duplicate"; } value = cf->args->elts; - lcf->error_log = ngx_log_create(cf->cycle, &value[1]); - if (lcf->error_log == NULL) { + clcf->error_log = ngx_log_create(cf->cycle, &value[1]); + if (clcf->error_log == NULL) { return NGX_CONF_ERROR; } if (cf->args->nelts == 2) { - lcf->error_log->log_level = NGX_LOG_ERR; + clcf->error_log->log_level = NGX_LOG_ERR; return NGX_CONF_OK; } - return ngx_log_set_levels(cf, lcf->error_log); + return ngx_log_set_levels(cf, clcf->error_log); } static char * ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; ngx_str_t *value; - if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) { + if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) { return "is duplicate"; } value = cf->args->elts; - lcf->keepalive_timeout = ngx_parse_time(&value[1], 0); + clcf->keepalive_timeout = ngx_parse_time(&value[1], 0); - if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) { + if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) { return "invalid value"; } - if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { + if (clcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { return "value must be less than 597 hours"; } @@ -4164,13 +4129,13 @@ return NGX_CONF_OK; } - lcf->keepalive_header = ngx_parse_time(&value[2], 1); + clcf->keepalive_header = ngx_parse_time(&value[2], 1); - if (lcf->keepalive_header == NGX_ERROR) { + if (clcf->keepalive_header == NGX_ERROR) { return "invalid value"; } - if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) { + if (clcf->keepalive_header == NGX_PARSE_LARGE_TIME) { return "value must be less than 68 years"; } @@ -4181,13 +4146,13 @@ static char * ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_core_loc_conf_t *lcf = conf; + ngx_http_core_loc_conf_t *clcf = conf; - if (lcf->internal != NGX_CONF_UNSET) { + if (clcf->internal != NGX_CONF_UNSET) { return "is duplicate"; } - lcf->internal = 1; + clcf->internal = 1; return NGX_CONF_OK; } @@ -4235,10 +4200,11 @@ #if (NGX_PCRE) - ngx_str_t err, *value; - ngx_uint_t i; - ngx_regex_elt_t *re; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_str_t *value; + ngx_uint_t i; + ngx_regex_elt_t *re; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) { clcf->gzip_disable = ngx_array_create(cf->pool, 2, @@ -4250,9 +4216,12 @@ value = cf->args->elts; - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); + rc.pool = cf->pool; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + for (i = 1; i < cf->args->nelts; i++) { if (ngx_strcmp(value[1].data, "msie6") == 0) { @@ -4265,14 +4234,15 @@ return NGX_CONF_ERROR; } - re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool, - &err); + rc.pattern = value[1]; + rc.options = NGX_REGEX_CASELESS; - if (re->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + if (ngx_regex_compile(&rc) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); return NGX_CONF_ERROR; } + re->regex = rc.regex; re->name = value[i].data; } Index: src/http/modules/ngx_http_ssi_filter_module.c =================================================================== --- src/http/modules/ngx_http_ssi_filter_module.c (revision 2637) +++ src/http/modules/ngx_http_ssi_filter_module.c (working copy) @@ -2450,27 +2450,28 @@ } else { #if (NGX_PCRE) - ngx_str_t err; - ngx_regex_t *regex; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_regex_compile_t rgc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; - right.data[right.len] = '\0'; - regex = ngx_regex_compile(&right, 0, r->pool, &err); + ngx_memzero(&rgc, sizeof(ngx_regex_compile_t)); - if (regex == NULL) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", err.data); + rgc.pattern = right; + rgc.pool = r->pool; + rgc.err.len = NGX_MAX_CONF_ERRSTR; + rgc.err.data = errstr; + + if (ngx_regex_compile(&rgc) != NGX_OK) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err); return NGX_HTTP_SSI_ERROR; } - rc = ngx_regex_exec(regex, &left, NULL, 0); + rc = ngx_regex_exec(rgc.regex, &left, NULL, 0); - if (rc != NGX_REGEX_NO_MATCHED && rc < 0) { + if (rc < NGX_REGEX_NO_MATCHED) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", + ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", rc, &left, &right); return NGX_HTTP_SSI_ERROR; } Index: src/http/modules/ngx_http_rewrite_module.c =================================================================== --- src/http/modules/ngx_http_rewrite_module.c (revision 2639) +++ src/http/modules/ngx_http_rewrite_module.c (working copy) @@ -294,9 +294,9 @@ { ngx_http_rewrite_loc_conf_t *lcf = conf; - ngx_str_t *value, err; - ngx_int_t n; + ngx_str_t *value; ngx_uint_t last; + ngx_regex_compile_t rc; ngx_http_script_code_pt *code; ngx_http_script_compile_t sc; ngx_http_script_regex_code_t *regex; @@ -313,15 +313,16 @@ value = cf->args->elts; - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); + rc.pattern = value[1]; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + /* TODO: NGX_REGEX_CASELESS */ - regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); - + regex->regex = ngx_http_regex_compile(cf, &rc); if (regex->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); return NGX_CONF_ERROR; } @@ -394,7 +395,6 @@ regex = sc.main; - regex->ncaptures = sc.ncaptures; regex->size = sc.size; regex->args = sc.args; @@ -402,31 +402,6 @@ regex->lengths = NULL; } - n = ngx_regex_capture_count(regex->regex); - - if (n < 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - ngx_regex_capture_count_n " failed for " - "pattern \"%V\"", &value[1]); - return NGX_CONF_ERROR; - } - - if (regex->ncaptures > (ngx_uint_t) n) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "pattern \"%V\" has less captures " - "than referrenced in substitution \"%V\"", - &value[1], &value[2]); - return NGX_CONF_ERROR; - } - - if (regex->ncaptures < (ngx_uint_t) n) { - regex->ncaptures = (ngx_uint_t) n; - } - - if (regex->ncaptures) { - regex->ncaptures = (regex->ncaptures + 1) * 3; - } - regex_end = ngx_http_script_add_code(lcf->codes, sizeof(ngx_http_script_regex_end_code_t), ®ex); @@ -624,8 +599,9 @@ { u_char *p; size_t len; - ngx_str_t *value, err; - ngx_uint_t cur, last, n; + ngx_str_t *value; + ngx_uint_t cur, last; + ngx_regex_compile_t rc; ngx_http_script_code_pt *code; ngx_http_script_file_code_t *fop; ngx_http_script_regex_code_t *regex; @@ -733,15 +709,15 @@ ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); - regex->regex = ngx_regex_compile(&value[last], - (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0, - cf->pool, &err); + rc.pattern = value[last]; + rc.options = (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + regex->regex = ngx_http_regex_compile(cf, &rc); if (regex->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); return NGX_CONF_ERROR; } @@ -753,12 +729,6 @@ } regex->name = value[last]; - n = ngx_regex_capture_count(regex->regex); - - if (n) { - regex->ncaptures = (n + 1) * 3; - } - return NGX_CONF_OK; } Index: src/http/modules/ngx_http_referer_module.c =================================================================== --- src/http/modules/ngx_http_referer_module.c (revision 2639) +++ src/http/modules/ngx_http_referer_module.c (working copy) @@ -412,7 +412,7 @@ if (sn[n].regex) { if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name, - sn[n].regex) + sn[n].regex->regex) != NGX_OK) { return NGX_CONF_ERROR; @@ -502,9 +502,9 @@ ngx_str_t *name, ngx_regex_t *regex) { #if (NGX_PCRE) - ngx_str_t err; - ngx_regex_elt_t *re; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_regex_elt_t *re; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; if (name->len == 1) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name); @@ -530,19 +530,23 @@ return NGX_CONF_OK; } - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; - name->len--; name->data++; - re->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err); + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); - if (re->regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + rc.pattern = *name; + rc.pool = cf->pool; + rc.options = NGX_REGEX_CASELESS; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; + + if (ngx_regex_compile(&rc) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); return NGX_CONF_ERROR; } + re->regex = rc.regex; re->name = name->data; return NGX_CONF_OK; Index: src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- src/http/modules/ngx_http_fastcgi_module.c (revision 2639) +++ src/http/modules/ngx_http_fastcgi_module.c (working copy) @@ -2518,39 +2518,41 @@ #if (NGX_PCRE) ngx_http_fastcgi_loc_conf_t *flcf = conf; - ngx_int_t n; - ngx_str_t *value, err; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + ngx_str_t *value; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; value = cf->args->elts; flcf->split_name = value[1]; - err.len = NGX_MAX_CONF_ERRSTR; - err.data = errstr; + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); - flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); + rc.pattern = value[1]; + rc.pool = cf->pool; + rc.err.len = NGX_MAX_CONF_ERRSTR; + rc.err.data = errstr; - if (flcf->split_regex == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + if (ngx_regex_compile(&rc) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); return NGX_CONF_ERROR; } - n = ngx_regex_capture_count(flcf->split_regex); - - if (n < 0) { + if (rc.captures < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ngx_regex_capture_count_n " failed for " "pattern \"%V\"", &value[1]); return NGX_CONF_ERROR; } - if (n != 2) { + if (rc.captures != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "pattern \"%V\" must have 2 captures", &value[1]); return NGX_CONF_ERROR; } + flcf->split_regex = rc.regex; + return NGX_CONF_OK; #else Index: src/http/ngx_http_request.c =================================================================== --- src/http/ngx_http_request.c (revision 2639) +++ src/http/ngx_http_request.c (working copy) @@ -1700,7 +1700,6 @@ #if (NGX_PCRE) if (len && r->virtual_names->nregex) { - size_t ncaptures; ngx_int_t n; ngx_uint_t i; ngx_str_t name; @@ -1709,33 +1708,17 @@ name.len = len; name.data = host; - ncaptures = 0; - sn = r->virtual_names->regex; for (i = 0; i < r->virtual_names->nregex; i++) { - if (sn[i].server->captures && r->captures == NULL) { + n = ngx_http_regex_exec(r, sn[i].regex, &name); - ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3; - - r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int)); - if (r->captures == NULL) { - return NGX_ERROR; - } - } - - n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures); - - if (n == NGX_REGEX_NO_MATCHED) { + if (n == NGX_DECLINED) { continue; } if (n < 0) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n - " failed: %d on \"%V\" using \"%V\"", - n, &name, &sn[i].name); return NGX_ERROR; } @@ -1743,9 +1726,6 @@ cscf = sn[i].server; - r->ncaptures = ncaptures; - r->captures_data = host; - goto found; } } Index: src/http/ngx_http_core_module.h =================================================================== --- src/http/ngx_http_core_module.h (revision 2639) +++ src/http/ngx_http_core_module.h (working copy) @@ -126,6 +126,7 @@ ngx_hash_t variables_hash; ngx_array_t variables; /* ngx_http_variable_t */ + ngx_uint_t ncaptures; ngx_uint_t server_names_hash_max_size; ngx_uint_t server_names_hash_bucket_size; @@ -238,7 +239,7 @@ struct ngx_http_server_name_s { #if (NGX_PCRE) - ngx_regex_t *regex; + ngx_http_regex_t *regex; #endif ngx_http_core_srv_conf_t *server; /* virtual name server conf */ ngx_str_t name; @@ -267,9 +268,7 @@ ngx_str_t name; /* location name */ #if (NGX_PCRE) - ngx_regex_t *regex; - - unsigned captures:1; + ngx_http_regex_t *regex; #endif unsigned noname:1; /* "if () {}" block or limit_except */ Index: src/http/ngx_http_script.c =================================================================== --- src/http/ngx_http_script.c (revision 2639) +++ src/http/ngx_http_script.c (working copy) @@ -828,20 +828,9 @@ e->line.data = e->sp->data; } - if (code->ncaptures && r->captures == NULL) { + rc = ngx_http_regex_exec(r, code->regex, &e->line); - r->captures = ngx_palloc(r->pool, - (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int)); - if (r->captures == NULL) { - e->ip = ngx_http_script_exit; - e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; - return; - } - } - - rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures); - - if (rc == NGX_REGEX_NO_MATCHED) { + if (rc == NGX_DECLINED) { if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "\"%V\" does not match \"%V\"", @@ -885,9 +874,6 @@ "\"%V\" matches \"%V\"", &code->name, &e->line); } - r->ncaptures = code->ncaptures; - r->captures_data = e->line.data; - if (code->test) { if (code->negative_test) { e->sp->len = 0; Index: src/http/ngx_http_variables.c =================================================================== --- src/http/ngx_http_variables.c (revision 2639) +++ src/http/ngx_http_variables.c (working copy) @@ -1666,7 +1666,158 @@ } +static ngx_int_t +ngx_http_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) +{ + v->not_found = 1; + return NGX_OK; +} + + +ngx_http_regex_t * +ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc) +{ + u_char *p; + size_t size; + ngx_str_t name; + ngx_uint_t i, n; + ngx_http_variable_t *v; + ngx_http_regex_t *re; + ngx_http_regex_variable_t *rv; + ngx_http_core_main_conf_t *cmcf; + + rc->pool = cf->pool; + + if (ngx_regex_compile(rc) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err); + return NULL; + } + + re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t)); + if (re == NULL) { + return NULL; + } + + re->regex = rc->regex; + re->ncaptures = rc->captures; + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures); + + n = (ngx_uint_t) rc->named_captures; + + if (n == 0) { + return re; + } + + rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t)); + if (rv == NULL) { + return NULL; + } + + re->variables = rv; + re->nvariables = n; + re->name = rc->pattern; + + size = rc->name_size; + p = rc->names; + + for (i = 0; i < n; i++) { + rv[i].capture = 2 * ((p[0] << 8) + p[1]); + + name.data = &p[2]; + name.len = ngx_strlen(name.data); + + v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); + if (v == NULL) { + return NULL; + } + + rv[i].index = ngx_http_get_variable_index(cf, &name); + if (rv[i].index == NGX_ERROR) { + return NULL; + } + + v->get_handler = ngx_http_variable_not_found; + + p += i + size; + } + + return re; +} + + ngx_int_t +ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s) +{ + ngx_int_t rc, index; + ngx_uint_t i, n, len; + ngx_http_variable_value_t *vv; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + if (re->ncaptures) { + len = (cmcf->ncaptures + 1) * 3; + + if (r->captures == NULL) { + r->captures = ngx_palloc(r->pool, len * sizeof(int)); + if (r->captures == NULL) { + return NGX_ERROR; + } + } + + } else { + len = 0; + } + + rc = ngx_regex_exec(re->regex, s, r->captures, len); + + if (rc == NGX_REGEX_NO_MATCHED) { + return NGX_DECLINED; + } + + if (rc < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", + rc, s, &re->name); + return NGX_ERROR; + } + + for (i = 0; i < re->nvariables; i++) { + + n = re->variables[i].capture; + index = re->variables[i].index; + vv = &r->variables[index]; + + vv->len = r->captures[n + 1] - r->captures[n]; + vv->valid = 1; + vv->no_cacheable = 0; + vv->not_found = 0; + vv->data = &s->data[r->captures[n]]; + +#if (NGX_DEBUG) + { + ngx_http_variable_t *v; + + v = cmcf->variables.elts; + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http regex set $%V to \"%*s\"", + &v[index].name, vv->len, vv->data); + } +#endif + } + + r->ncaptures = len; + r->captures_data = s->data; + + return NGX_OK; +} + + +ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf) { ngx_int_t rc; Index: src/http/ngx_http_script.h =================================================================== --- src/http/ngx_http_script.h (revision 2639) +++ src/http/ngx_http_script.h (working copy) @@ -114,10 +114,9 @@ typedef struct { ngx_http_script_code_pt code; - ngx_regex_t *regex; + ngx_http_regex_t *regex; ngx_array_t *lengths; uintptr_t size; - uintptr_t ncaptures; uintptr_t status; uintptr_t next; Index: src/http/ngx_http_variables.h =================================================================== --- src/http/ngx_http_variables.h (revision 2639) +++ src/http/ngx_http_variables.h (working copy) @@ -41,6 +41,21 @@ }; +typedef struct { + ngx_uint_t capture; + ngx_int_t index; +} ngx_http_regex_variable_t; + + +typedef struct { + ngx_regex_t *regex; + ngx_uint_t ncaptures; + ngx_http_regex_variable_t *variables; + ngx_uint_t nvariables; + ngx_str_t name; +} ngx_http_regex_t; + + ngx_http_variable_t *ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags); ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name); @@ -59,6 +74,12 @@ #define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL; +ngx_http_regex_t *ngx_http_regex_compile(ngx_conf_t *cf, + ngx_regex_compile_t *rc); +ngx_int_t ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, + ngx_str_t *s); + + ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf); ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf); Index: src/core/ngx_regex.c =================================================================== --- src/core/ngx_regex.c (revision 2637) +++ src/core/ngx_regex.c (working copy) @@ -23,25 +23,16 @@ } -ngx_regex_t * -ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, - ngx_str_t *err) +static ngx_inline void +ngx_regex_malloc_init(ngx_pool_t *pool) { - int erroff; - const char *errstr; - ngx_regex_t *re; #if (NGX_THREADS) ngx_core_tls_t *tls; -#if (NGX_SUPPRESS_WARN) - tls = NULL; -#endif - if (ngx_threaded) { tls = ngx_thread_get_tls(ngx_core_tls_key); tls->pool = pool; - } else { - ngx_pcre_pool = pool; + return; } #else @@ -49,35 +40,103 @@ ngx_pcre_pool = pool; #endif +} - re = pcre_compile((const char *) pattern->data, (int) options, + +static ngx_inline void +ngx_regex_malloc_done(void) +{ +#if (NGX_THREADS) + ngx_core_tls_t *tls; + + if (ngx_threaded) { + tls = ngx_thread_get_tls(ngx_core_tls_key); + tls->pool = NULL; + return; + } + +#else + + ngx_pcre_pool = NULL; + +#endif +} + + +ngx_int_t +ngx_regex_compile(ngx_regex_compile_t *rc) +{ + int n, erroff; + char *p; + const char *errstr; + ngx_regex_t *re; + + ngx_regex_malloc_init(rc->pool); + + re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, &errstr, &erroff, NULL); + /* ensure that there is no current pool */ + ngx_regex_malloc_done(); + if (re == NULL) { - if ((size_t) erroff == pattern->len) { - ngx_snprintf(err->data, err->len - 1, - "pcre_compile() failed: %s in \"%s\"%Z", - errstr, pattern->data); + if ((size_t) erroff == rc->pattern.len) { + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre_compile() failed: %s in \"%V\"", + errstr, &rc->pattern) + - rc->err.data; + } else { - ngx_snprintf(err->data, err->len - 1, - "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z", - errstr, pattern->data, pattern->data + erroff); + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre_compile() failed: %s in \"%V\" at \"%s\"", + errstr, &rc->pattern, rc->pattern.data + erroff) + - rc->err.data; } + + return NGX_ERROR; } - /* ensure that there is no current pool */ + rc->regex = re; -#if (NGX_THREADS) - if (ngx_threaded) { - tls->pool = NULL; - } else { - ngx_pcre_pool = NULL; + n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); + if (n < 0) { + p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; + goto failed; } -#else - ngx_pcre_pool = NULL; -#endif - return re; + if (rc->captures == 0) { + return NGX_OK; + } + + n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures); + if (n < 0) { + p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d"; + goto failed; + } + + if (rc->named_captures == 0) { + return NGX_OK; + } + + n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size); + if (n < 0) { + p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d"; + goto failed; + } + + n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names); + if (n < 0) { + p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d"; + goto failed; + } + + return NGX_OK; + +failed: + + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) + - rc->err.data; + return NGX_OK; } @@ -99,22 +158,6 @@ ngx_int_t -ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size) -{ - int rc; - - rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0, - captures, size); - - if (rc == -1) { - return NGX_REGEX_NO_MATCHED; - } - - return rc; -} - - -ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) { ngx_int_t n; @@ -157,11 +200,15 @@ if (ngx_threaded) { tls = ngx_thread_get_tls(ngx_core_tls_key); pool = tls->pool; + } else { pool = ngx_pcre_pool; } + #else + pool = ngx_pcre_pool; + #endif if (pool) { Index: src/core/ngx_regex.h =================================================================== --- src/core/ngx_regex.h (revision 2637) +++ src/core/ngx_regex.h (working copy) @@ -14,24 +14,41 @@ #include -#define NGX_REGEX_NO_MATCHED -1000 +#define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */ #define NGX_REGEX_CASELESS PCRE_CASELESS typedef pcre ngx_regex_t; + typedef struct { - ngx_regex_t *regex; - u_char *name; + ngx_str_t pattern; + ngx_pool_t *pool; + ngx_int_t options; + + ngx_regex_t *regex; + int captures; + int named_captures; + int name_size; + u_char *names; + ngx_str_t err; +} ngx_regex_compile_t; + + +typedef struct { + ngx_regex_t *regex; + u_char *name; } ngx_regex_elt_t; void ngx_regex_init(void); -ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, - ngx_pool_t *pool, ngx_str_t *err); +ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc); ngx_int_t ngx_regex_capture_count(ngx_regex_t *re); -ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, - ngx_int_t size); + +#define ngx_regex_exec(re, s, captures, size) \ + pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \ + captures, size) + ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log); Index: src/core/ngx_core.h =================================================================== --- src/core/ngx_core.h (revision 2639) +++ src/core/ngx_core.h (working copy) @@ -83,7 +83,8 @@ #define CRLF "\x0d\x0a" -#define ngx_abs(value) (((value) >= 0) ? (value) : - (value)) +#define ngx_abs(value) (((value) >= 0) ? (value) : - (value)) +#define ngx_max(val1, val2) ((val1 < val2) ? (val2) : (val1)) void ngx_cpuinfo(void);