mirror of
https://github.com/nginx/nginx.git
synced 2025-06-08 02:02:38 +08:00
regex named captures
This commit is contained in:
parent
c0ae4716ec
commit
c05f20ec2e
@ -83,7 +83,8 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
|
||||
#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);
|
||||
|
||||
|
@ -23,25 +23,16 @@ 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)
|
||||
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_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
|
||||
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);
|
||||
|
||||
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);
|
||||
} else {
|
||||
ngx_snprintf(err->data, err->len - 1,
|
||||
"pcre_compile() failed: %s in \"%s\" at \"%s\"%Z",
|
||||
errstr, pattern->data, pattern->data + erroff);
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure that there is no current pool */
|
||||
ngx_regex_malloc_done();
|
||||
|
||||
#if (NGX_THREADS)
|
||||
if (ngx_threaded) {
|
||||
tls->pool = NULL;
|
||||
} else {
|
||||
ngx_pcre_pool = NULL;
|
||||
if (re == NULL) {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
#else
|
||||
ngx_pcre_pool = NULL;
|
||||
#endif
|
||||
|
||||
return re;
|
||||
rc->regex = re;
|
||||
|
||||
n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
|
||||
if (n < 0) {
|
||||
p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -117,7 +176,7 @@ ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
|
||||
|
||||
if (n < 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"",
|
||||
ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
|
||||
n, s, re[i].name);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -141,11 +200,15 @@ ngx_regex_malloc(size_t size)
|
||||
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) {
|
||||
|
@ -20,26 +20,36 @@
|
||||
|
||||
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_capture_count(ngx_regex_t *re);
|
||||
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
|
||||
|
||||
#define ngx_regex_exec(re, s, captures, size) \
|
||||
pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \
|
||||
captures, size)
|
||||
#define ngx_regex_exec_n "pcre_exec()"
|
||||
|
||||
ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
|
||||
|
||||
|
||||
#define ngx_regex_exec_n "pcre_exec()"
|
||||
#define ngx_regex_capture_count_n "pcre_fullinfo()"
|
||||
|
||||
|
||||
#endif /* _NGX_REGEX_H_INCLUDED_ */
|
||||
|
@ -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 >= 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 == NGX_REGEX_NO_MATCHED) {
|
||||
f->script_name = r->uri;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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) {
|
||||
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
|
||||
|
@ -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));
|
||||
|
||||
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;
|
||||
|
@ -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));
|
||||
|
||||
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 @@ 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),
|
||||
®ex);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
rc = ngx_http_core_find_location(r);
|
||||
|
||||
return (rc == NGX_ERROR) ? rc : NGX_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
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\"",
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user