aboutsummaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c61
-rw-r--r--src/http/modules/ngx_http_referer_module.c24
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c64
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c23
-rw-r--r--src/http/ngx_http_core_module.c120
-rw-r--r--src/http/ngx_http_core_module.h7
-rw-r--r--src/http/ngx_http_request.c35
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_script.c26
-rw-r--r--src/http/ngx_http_script.h3
-rw-r--r--src/http/ngx_http_variables.c151
-rw-r--r--src/http/ngx_http_variables.h21
12 files changed, 299 insertions, 237 deletions
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index ba79cea0f..d7aa9b259 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2407,27 +2407,25 @@ ngx_http_fastcgi_split(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf)
n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
- if (n == NGX_REGEX_NO_MATCHED) {
- f->script_name = r->uri;
+ if (n >= 0) { /* match */
+ f->script_name.len = captures[3] - captures[2];
+ f->script_name.data = r->uri.data;
+
+ f->path_info.len = captures[5] - captures[4];
+ f->path_info.data = r->uri.data + f->script_name.len;
+
return f;
}
- 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, &flcf->split_name);
- return NULL;
+ if (n == NGX_REGEX_NO_MATCHED) {
+ f->script_name = r->uri;
+ return f;
}
- /* match */
-
- f->script_name.len = captures[3] - captures[2];
- f->script_name.data = r->uri.data;
-
- f->path_info.len = captures[5] - captures[4];
- f->path_info.data = r->uri.data + f->script_name.len;
-
- return f;
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
+ n, &r->uri, &flcf->split_name);
+ return NULL;
#else
@@ -2518,39 +2516,34 @@ ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#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;
-
- flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
-
- if (flcf->split_regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
- return NGX_CONF_ERROR;
- }
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- n = ngx_regex_capture_count(flcf->split_regex);
+ rc.pattern = value[1];
+ rc.pool = cf->pool;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- if (n < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- ngx_regex_capture_count_n " failed for "
- "pattern \"%V\"", &value[1]);
+ if (ngx_regex_compile(&rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
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
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 8daa399bd..e655be967 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -412,7 +412,7 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
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 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
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));
+
+ rc.pattern = *name;
+ rc.pool = cf->pool;
+ rc.options = NGX_REGEX_CASELESS;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- 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 = name->data;
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 1f98cf829..b07eedc78 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -294,9 +294,9 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
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 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- /* TODO: NGX_REGEX_CASELESS */
+ rc.pattern = value[1];
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
+ /* TODO: NGX_REGEX_CASELESS */
+ 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 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
regex = sc.main;
- regex->ncaptures = sc.ncaptures;
regex->size = sc.size;
regex->args = sc.args;
@@ -402,31 +402,6 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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),
&regex);
@@ -624,8 +599,9 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
{
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_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
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 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
}
regex->name = value[last];
- n = ngx_regex_capture_count(regex->regex);
-
- if (n) {
- regex->ncaptures = (n + 1) * 3;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index f06994db3..1b9a3a037 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -2450,27 +2450,28 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
} else {
#if (NGX_PCRE)
- ngx_str_t err;
- ngx_regex_t *regex;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_regex_compile_t rgc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
right.data[right.len] = '\0';
- regex = ngx_regex_compile(&right, 0, r->pool, &err);
+ ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
+
+ rgc.pattern = right;
+ rgc.pool = r->pool;
+ rgc.err.len = NGX_MAX_CONF_ERRSTR;
+ rgc.err.data = errstr;
- if (regex == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", err.data);
+ 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) {
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;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index be4f1958d..7ae49a686 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1420,7 +1420,7 @@ ngx_http_core_find_location(ngx_http_request_t *r)
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,51 +1454,28 @@ ngx_http_core_find_location(ngx_http_request_t *r)
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 (n == NGX_OK) {
+ r->loc_conf = (*clcfp)->loc_conf;
- if (r->captures == NULL) {
- r->captures = ngx_palloc(r->pool, len * sizeof(int));
- if (r->captures == NULL) {
- return NGX_ERROR;
- }
- }
- }
+ /* look up nested locations */
- n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len);
+ rc = ngx_http_core_find_location(r);
- if (n == NGX_REGEX_NO_MATCHED) {
- continue;
+ return (rc == NGX_ERROR) ? rc : NGX_OK;
}
- 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);
- return NGX_ERROR;
+ if (n == NGX_DECLINED) {
+ continue;
}
- /* match */
-
- 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);
-
- return (rc == NGX_ERROR) ? rc : NGX_OK;
+ return NGX_ERROR;
}
}
#endif
@@ -1778,7 +1755,7 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
#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 +2573,25 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
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;
@@ -3535,8 +3511,8 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#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 +3520,22 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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,
@@ -3665,20 +3642,6 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
-#if (NGX_PCRE)
-
- if (alias && clcf->regex
- && (ngx_regex_capture_count(clcf->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;
}
@@ -4235,10 +4198,11 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#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,8 +4214,11 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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++) {
@@ -4265,14 +4232,15 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
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;
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 2b8d8bb31..c240f252c 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -126,6 +126,7 @@ typedef struct {
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 @@ typedef struct {
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 @@ struct ngx_http_core_loc_conf_s {
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 */
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 3f399320b..30639810d 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1700,7 +1700,6 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
#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,44 +1708,22 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
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) {
-
- ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
+ n = ngx_http_regex_exec(r, sn[i].regex, &name);
- r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int));
- if (r->captures == NULL) {
- return NGX_ERROR;
- }
+ if (n == NGX_OK) {
+ cscf = sn[i].server;
+ goto found;
}
- 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;
- }
-
- /* match */
-
- cscf = sn[i].server;
-
- r->ncaptures = ncaptures;
- r->captures_data = host;
-
- goto found;
+ return NGX_ERROR;
}
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 15c0eb94a..79ec02873 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -10,7 +10,6 @@
#define NGX_HTTP_MAX_URI_CHANGES 10
#define NGX_HTTP_MAX_SUBREQUESTS 50
-#define NGX_HTTP_MAX_CAPTURES 9
/* must be 2^n */
#define NGX_HTTP_LC_HEADER_LEN 32
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index f79345715..b809e2b98 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -251,8 +251,6 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
{
ngx_uint_t n;
- /* NGX_HTTP_MAX_CAPTURES is 9 */
-
if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
n = sc->source->data[i] - '0';
@@ -828,20 +826,9 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
e->line.data = e->sp->data;
}
- if (code->ncaptures && r->captures == NULL) {
-
- 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);
+ rc = ngx_http_regex_exec(r, code->regex, &e->line);
- 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\"",
@@ -870,11 +857,7 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
return;
}
- if (rc < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
- rc, &e->line, &code->name);
-
+ if (rc == NGX_ERROR) {
e->ip = ngx_http_script_exit;
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
return;
@@ -885,9 +868,6 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
"\"%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;
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
index ea97069e6..90a4e1a06 100644
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -114,10 +114,9 @@ typedef struct {
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;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index cf87f3fac..633b31084 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1666,6 +1666,157 @@ ngx_http_variable_pid(ngx_http_request_t *r,
}
+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)
{
diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h
index 0e86aaf3d..2056befc5 100644
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -41,6 +41,21 @@ struct ngx_http_variable_s {
};
+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 @@ ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
#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);