mirror of
https://github.com/nginx/nginx.git
synced 2025-08-06 14:56:15 +08:00
ngx_http_script_flush_complex_value()
ngx_http_complex_value() ngx_http_compile_complex_value()
This commit is contained in:
parent
c7ce3a99bc
commit
8508c10bb8
@ -12,7 +12,7 @@
|
||||
static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
|
||||
static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
|
||||
static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
|
||||
ngx_str_t *value);
|
||||
ngx_str_t *value, ngx_uint_t last);
|
||||
static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
|
||||
ngx_str_t *name);
|
||||
static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
|
||||
@ -20,6 +20,10 @@ static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
|
||||
static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
|
||||
ngx_uint_t n);
|
||||
#endif
|
||||
static ngx_int_t
|
||||
ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
|
||||
static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
|
||||
static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
|
||||
|
||||
|
||||
#define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
|
||||
@ -27,6 +31,186 @@ static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
|
||||
static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
|
||||
|
||||
|
||||
void
|
||||
ngx_http_scrip_flush_complex_value(ngx_http_request_t *r,
|
||||
ngx_http_complex_value_t *val)
|
||||
{
|
||||
ngx_uint_t *index;
|
||||
|
||||
index = val->flushes;
|
||||
|
||||
if (index) {
|
||||
while (*index != (ngx_uint_t) -1) {
|
||||
|
||||
if (r->variables[*index].no_cacheable) {
|
||||
r->variables[*index].valid = 0;
|
||||
r->variables[*index].not_found = 0;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
size_t len;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_len_code_pt lcode;
|
||||
ngx_http_script_engine_t e;
|
||||
|
||||
if (val->lengths == NULL) {
|
||||
*value = val->value;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_http_scrip_flush_complex_value(r, val);
|
||||
|
||||
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
e.ip = val->lengths;
|
||||
e.request = r;
|
||||
e.flushed = 1;
|
||||
|
||||
len = 0;
|
||||
|
||||
while (*(uintptr_t *) e.ip) {
|
||||
lcode = *(ngx_http_script_len_code_pt *) e.ip;
|
||||
len += lcode(&e);
|
||||
}
|
||||
|
||||
value->len = len;
|
||||
value->data = ngx_pnalloc(r->pool, len);
|
||||
if (value->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
e.ip = val->values;
|
||||
e.pos = value->data;
|
||||
e.buf = *value;
|
||||
|
||||
while (*(uintptr_t *) e.ip) {
|
||||
code = *(ngx_http_script_code_pt *) e.ip;
|
||||
code((ngx_http_script_engine_t *) &e);
|
||||
}
|
||||
|
||||
*value = e.buf;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
|
||||
{
|
||||
ngx_str_t *v;
|
||||
ngx_uint_t i, n, nv, nc;
|
||||
ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
v = ccv->value;
|
||||
|
||||
if (v->len == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ccv->complex_value->value = *v;
|
||||
ccv->complex_value->flushes = NULL;
|
||||
ccv->complex_value->lengths = NULL;
|
||||
ccv->complex_value->values = NULL;
|
||||
|
||||
nv = 0;
|
||||
nc = 0;
|
||||
|
||||
for (i = 0; i < v->len; i++) {
|
||||
if (v->data[i] == '$') {
|
||||
if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
|
||||
nc++;
|
||||
|
||||
} else {
|
||||
nv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) {
|
||||
|
||||
if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ccv->conf_prefix = 0;
|
||||
ccv->root_prefix = 0;
|
||||
}
|
||||
|
||||
if (nv == 0 && nc == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
n = nv + 1;
|
||||
|
||||
if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
|
||||
+ sizeof(ngx_http_script_var_code_t))
|
||||
+ sizeof(uintptr_t);
|
||||
|
||||
if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
|
||||
+ sizeof(ngx_http_script_var_code_t))
|
||||
+ sizeof(uintptr_t)
|
||||
+ v->len
|
||||
+ sizeof(uintptr_t) - 1)
|
||||
& ~(sizeof(uintptr_t) - 1);
|
||||
|
||||
if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
pf = &flushes;
|
||||
pl = &lengths;
|
||||
pv = &values;
|
||||
|
||||
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
|
||||
|
||||
sc.cf = ccv->cf;
|
||||
sc.source = v;
|
||||
sc.flushes = &pf;
|
||||
sc.lengths = &pl;
|
||||
sc.values = &pv;
|
||||
sc.complete_lengths = 1;
|
||||
sc.complete_values = 1;
|
||||
sc.zero = ccv->zero;
|
||||
sc.conf_prefix = ccv->conf_prefix;
|
||||
sc.root_prefix = ccv->root_prefix;
|
||||
|
||||
if (ngx_http_script_compile(&sc) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (flushes.nelts) {
|
||||
ccv->complex_value->flushes = flushes.elts;
|
||||
ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
|
||||
}
|
||||
|
||||
ccv->complex_value->lengths = lengths.elts;
|
||||
ccv->complex_value->values = values.elts;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_uint_t
|
||||
ngx_http_script_variables_count(ngx_str_t *value)
|
||||
{
|
||||
@ -180,7 +364,9 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
|
||||
|
||||
sc->size += name.len;
|
||||
|
||||
if (ngx_http_script_add_copy_code(sc, &name) != NGX_OK) {
|
||||
if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
@ -309,8 +495,25 @@ ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
|
||||
static ngx_int_t
|
||||
ngx_http_script_done(ngx_http_script_compile_t *sc)
|
||||
{
|
||||
ngx_str_t zero;
|
||||
uintptr_t *code;
|
||||
|
||||
if (sc->zero) {
|
||||
|
||||
zero.len = 1;
|
||||
zero.data = (u_char *) "\0";
|
||||
|
||||
if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->conf_prefix || sc->root_prefix) {
|
||||
if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->complete_lengths) {
|
||||
code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
|
||||
if (code == NULL) {
|
||||
@ -373,11 +576,16 @@ ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value)
|
||||
ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
|
||||
ngx_uint_t last)
|
||||
{
|
||||
size_t size;
|
||||
u_char *p;
|
||||
size_t size, len, zero;
|
||||
ngx_http_script_copy_code_t *code;
|
||||
|
||||
zero = (sc->zero && last);
|
||||
len = value->len + zero;
|
||||
|
||||
code = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_copy_code_t), NULL);
|
||||
if (code == NULL) {
|
||||
@ -385,10 +593,9 @@ ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value)
|
||||
}
|
||||
|
||||
code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
|
||||
code->len = value->len;
|
||||
code->len = len;
|
||||
|
||||
size = (sizeof(ngx_http_script_copy_code_t) + value->len
|
||||
+ sizeof(uintptr_t) - 1)
|
||||
size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
|
||||
& ~(sizeof(uintptr_t) - 1);
|
||||
|
||||
code = ngx_http_script_add_code(*sc->values, size, &sc->main);
|
||||
@ -397,10 +604,15 @@ ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value)
|
||||
}
|
||||
|
||||
code->code = ngx_http_script_copy_code;
|
||||
code->len = value->len;
|
||||
code->len = len;
|
||||
|
||||
ngx_memcpy((u_char *) code + sizeof(ngx_http_script_copy_code_t),
|
||||
value->data, value->len);
|
||||
p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
|
||||
value->data, value->len);
|
||||
|
||||
if (zero) {
|
||||
*p = '\0';
|
||||
sc->zero = 0;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -988,6 +1200,77 @@ ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
|
||||
{
|
||||
ngx_http_script_full_name_code_t *code;
|
||||
|
||||
code = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_full_name_code_t),
|
||||
NULL);
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
|
||||
code->prefix = sc->conf_prefix;
|
||||
|
||||
code = ngx_http_script_add_code(*sc->values,
|
||||
sizeof(ngx_http_script_full_name_code_t),
|
||||
&sc->main);
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
code->code = ngx_http_script_full_name_code;
|
||||
code->prefix = sc->conf_prefix;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_full_name_code_t *code;
|
||||
|
||||
code = (ngx_http_script_full_name_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_full_name_code_t);
|
||||
|
||||
return code->prefix ? sizeof(NGX_CONF_PREFIX) : ngx_cycle->root.len;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_full_name_code_t *code;
|
||||
|
||||
ngx_str_t value;
|
||||
|
||||
code = (ngx_http_script_full_name_code_t *) e->ip;
|
||||
|
||||
value.data = e->buf.data;
|
||||
value.len = e->pos - e->buf.data;
|
||||
|
||||
if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->prefix)
|
||||
!= NGX_OK)
|
||||
{
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
e->buf = value;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script fullname: \"%V\"", &value);
|
||||
|
||||
e->ip += sizeof(ngx_http_script_full_name_code_t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_return_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
|
@ -53,86 +53,114 @@ typedef struct {
|
||||
unsigned compile_args:1;
|
||||
unsigned complete_lengths:1;
|
||||
unsigned complete_values:1;
|
||||
unsigned dup_capture:1;
|
||||
unsigned zero:1;
|
||||
unsigned conf_prefix:1;
|
||||
unsigned root_prefix:1;
|
||||
|
||||
unsigned dup_capture:1;
|
||||
unsigned args:1;
|
||||
} ngx_http_script_compile_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t value;
|
||||
ngx_uint_t *flushes;
|
||||
void *lengths;
|
||||
void *values;
|
||||
} ngx_http_complex_value_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_conf_t *cf;
|
||||
ngx_str_t *value;
|
||||
ngx_http_complex_value_t *complex_value;
|
||||
|
||||
unsigned zero:1;
|
||||
unsigned conf_prefix:1;
|
||||
unsigned root_prefix:1;
|
||||
} ngx_http_compile_complex_value_t;
|
||||
|
||||
|
||||
typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
|
||||
typedef size_t (*ngx_http_script_len_code_pt) (ngx_http_script_engine_t *e);
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t len;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t len;
|
||||
} ngx_http_script_copy_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t index;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t index;
|
||||
} ngx_http_script_var_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_set_variable_pt handler;
|
||||
uintptr_t data;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_set_variable_pt handler;
|
||||
uintptr_t data;
|
||||
} ngx_http_script_var_handler_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t n;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t n;
|
||||
} ngx_http_script_copy_capture_code_t;
|
||||
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_regex_t *regex;
|
||||
ngx_array_t *lengths;
|
||||
uintptr_t size;
|
||||
uintptr_t ncaptures;
|
||||
uintptr_t status;
|
||||
uintptr_t next;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_regex_t *regex;
|
||||
ngx_array_t *lengths;
|
||||
uintptr_t size;
|
||||
uintptr_t ncaptures;
|
||||
uintptr_t status;
|
||||
uintptr_t next;
|
||||
|
||||
uintptr_t test:1;
|
||||
uintptr_t negative_test:1;
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
uintptr_t test:1;
|
||||
uintptr_t negative_test:1;
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
|
||||
/* add the r->args to the new arguments */
|
||||
uintptr_t add_args:1;
|
||||
uintptr_t add_args:1;
|
||||
|
||||
uintptr_t redirect:1;
|
||||
uintptr_t break_cycle:1;
|
||||
uintptr_t redirect:1;
|
||||
uintptr_t break_cycle:1;
|
||||
|
||||
ngx_str_t name;
|
||||
ngx_str_t name;
|
||||
} ngx_http_script_regex_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_code_pt code;
|
||||
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
|
||||
/* add the r->args to the new arguments */
|
||||
uintptr_t add_args:1;
|
||||
uintptr_t add_args:1;
|
||||
|
||||
uintptr_t redirect:1;
|
||||
uintptr_t redirect:1;
|
||||
} ngx_http_script_regex_end_code_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t status;
|
||||
uintptr_t null;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t prefix;
|
||||
} ngx_http_script_full_name_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t status;
|
||||
uintptr_t null;
|
||||
} ngx_http_script_return_code_t;
|
||||
|
||||
|
||||
@ -149,32 +177,38 @@ typedef enum {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t op;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t op;
|
||||
} ngx_http_script_file_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t next;
|
||||
void **loc_conf;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t next;
|
||||
void **loc_conf;
|
||||
} ngx_http_script_if_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_array_t *lengths;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_array_t *lengths;
|
||||
} ngx_http_script_complex_value_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t value;
|
||||
uintptr_t text_len;
|
||||
uintptr_t text_data;
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t value;
|
||||
uintptr_t text_len;
|
||||
uintptr_t text_data;
|
||||
} ngx_http_script_value_code_t;
|
||||
|
||||
|
||||
void ngx_http_scrip_flush_complex_value(ngx_http_request_t *r,
|
||||
ngx_http_complex_value_t *val);
|
||||
ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
|
||||
ngx_http_complex_value_t *val, ngx_str_t *value);
|
||||
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
|
||||
|
||||
ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
|
||||
ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
|
||||
u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
|
||||
|
Loading…
Reference in New Issue
Block a user