Klaus Demo nginx / 8508c10
ngx_http_script_flush_complex_value() ngx_http_complex_value() ngx_http_compile_complex_value() Igor Sysoev 13 years ago
2 changed file(s) with 379 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
1111 static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
1212 static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
1313 static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
14 ngx_str_t *value);
14 ngx_str_t *value, ngx_uint_t last);
1515 static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
1616 ngx_str_t *name);
1717 static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
1919 static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
2020 ngx_uint_t n);
2121 #endif
22 static ngx_int_t
23 ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
24 static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
25 static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
2226
2327
2428 #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
2529
2630 static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
31
32
33 void
34 ngx_http_scrip_flush_complex_value(ngx_http_request_t *r,
35 ngx_http_complex_value_t *val)
36 {
37 ngx_uint_t *index;
38
39 index = val->flushes;
40
41 if (index) {
42 while (*index != (ngx_uint_t) -1) {
43
44 if (r->variables[*index].no_cacheable) {
45 r->variables[*index].valid = 0;
46 r->variables[*index].not_found = 0;
47 }
48
49 index++;
50 }
51 }
52 }
53
54
55 ngx_int_t
56 ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
57 ngx_str_t *value)
58 {
59 size_t len;
60 ngx_http_script_code_pt code;
61 ngx_http_script_len_code_pt lcode;
62 ngx_http_script_engine_t e;
63
64 if (val->lengths == NULL) {
65 *value = val->value;
66 return NGX_OK;
67 }
68
69 ngx_http_scrip_flush_complex_value(r, val);
70
71 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
72
73 e.ip = val->lengths;
74 e.request = r;
75 e.flushed = 1;
76
77 len = 0;
78
79 while (*(uintptr_t *) e.ip) {
80 lcode = *(ngx_http_script_len_code_pt *) e.ip;
81 len += lcode(&e);
82 }
83
84 value->len = len;
85 value->data = ngx_pnalloc(r->pool, len);
86 if (value->data == NULL) {
87 return NGX_ERROR;
88 }
89
90 e.ip = val->values;
91 e.pos = value->data;
92 e.buf = *value;
93
94 while (*(uintptr_t *) e.ip) {
95 code = *(ngx_http_script_code_pt *) e.ip;
96 code((ngx_http_script_engine_t *) &e);
97 }
98
99 *value = e.buf;
100
101 return NGX_OK;
102 }
103
104
105 ngx_int_t
106 ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
107 {
108 ngx_str_t *v;
109 ngx_uint_t i, n, nv, nc;
110 ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
111 ngx_http_script_compile_t sc;
112
113 v = ccv->value;
114
115 if (v->len == 0) {
116 ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter");
117 return NGX_ERROR;
118 }
119
120 ccv->complex_value->value = *v;
121 ccv->complex_value->flushes = NULL;
122 ccv->complex_value->lengths = NULL;
123 ccv->complex_value->values = NULL;
124
125 nv = 0;
126 nc = 0;
127
128 for (i = 0; i < v->len; i++) {
129 if (v->data[i] == '$') {
130 if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
131 nc++;
132
133 } else {
134 nv++;
135 }
136 }
137 }
138
139 if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) {
140
141 if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
142 return NGX_ERROR;
143 }
144
145 ccv->conf_prefix = 0;
146 ccv->root_prefix = 0;
147 }
148
149 if (nv == 0 && nc == 0) {
150 return NGX_OK;
151 }
152
153 n = nv + 1;
154
155 if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
156 != NGX_OK)
157 {
158 return NGX_ERROR;
159 }
160
161 n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
162 + sizeof(ngx_http_script_var_code_t))
163 + sizeof(uintptr_t);
164
165 if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
166 return NGX_ERROR;
167 }
168
169 n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
170 + sizeof(ngx_http_script_var_code_t))
171 + sizeof(uintptr_t)
172 + v->len
173 + sizeof(uintptr_t) - 1)
174 & ~(sizeof(uintptr_t) - 1);
175
176 if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
177 return NGX_ERROR;
178 }
179
180 pf = &flushes;
181 pl = &lengths;
182 pv = &values;
183
184 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
185
186 sc.cf = ccv->cf;
187 sc.source = v;
188 sc.flushes = &pf;
189 sc.lengths = &pl;
190 sc.values = &pv;
191 sc.complete_lengths = 1;
192 sc.complete_values = 1;
193 sc.zero = ccv->zero;
194 sc.conf_prefix = ccv->conf_prefix;
195 sc.root_prefix = ccv->root_prefix;
196
197 if (ngx_http_script_compile(&sc) != NGX_OK) {
198 return NGX_ERROR;
199 }
200
201 if (flushes.nelts) {
202 ccv->complex_value->flushes = flushes.elts;
203 ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
204 }
205
206 ccv->complex_value->lengths = lengths.elts;
207 ccv->complex_value->values = values.elts;
208
209 return NGX_OK;
210 }
27211
28212
29213 ngx_uint_t
179363
180364 sc->size += name.len;
181365
182 if (ngx_http_script_add_copy_code(sc, &name) != NGX_OK) {
366 if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
367 != NGX_OK)
368 {
183369 return NGX_ERROR;
184370 }
185371 }
308494 static ngx_int_t
309495 ngx_http_script_done(ngx_http_script_compile_t *sc)
310496 {
497 ngx_str_t zero;
311498 uintptr_t *code;
499
500 if (sc->zero) {
501
502 zero.len = 1;
503 zero.data = (u_char *) "\0";
504
505 if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
506 return NGX_ERROR;
507 }
508 }
509
510 if (sc->conf_prefix || sc->root_prefix) {
511 if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
512 return NGX_ERROR;
513 }
514 }
312515
313516 if (sc->complete_lengths) {
314517 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
372575
373576
374577 static ngx_int_t
375 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value)
376 {
377 size_t size;
578 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
579 ngx_uint_t last)
580 {
581 u_char *p;
582 size_t size, len, zero;
378583 ngx_http_script_copy_code_t *code;
584
585 zero = (sc->zero && last);
586 len = value->len + zero;
379587
380588 code = ngx_http_script_add_code(*sc->lengths,
381589 sizeof(ngx_http_script_copy_code_t), NULL);
384592 }
385593
386594 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
387 code->len = value->len;
388
389 size = (sizeof(ngx_http_script_copy_code_t) + value->len
390 + sizeof(uintptr_t) - 1)
595 code->len = len;
596
597 size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
391598 & ~(sizeof(uintptr_t) - 1);
392599
393600 code = ngx_http_script_add_code(*sc->values, size, &sc->main);
396603 }
397604
398605 code->code = ngx_http_script_copy_code;
399 code->len = value->len;
400
401 ngx_memcpy((u_char *) code + sizeof(ngx_http_script_copy_code_t),
402 value->data, value->len);
606 code->len = len;
607
608 p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
609 value->data, value->len);
610
611 if (zero) {
612 *p = '\0';
613 sc->zero = 0;
614 }
403615
404616 return NGX_OK;
405617 }
9871199 #endif
9881200
9891201
1202 static ngx_int_t
1203 ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
1204 {
1205 ngx_http_script_full_name_code_t *code;
1206
1207 code = ngx_http_script_add_code(*sc->lengths,
1208 sizeof(ngx_http_script_full_name_code_t),
1209 NULL);
1210 if (code == NULL) {
1211 return NGX_ERROR;
1212 }
1213
1214 code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
1215 code->prefix = sc->conf_prefix;
1216
1217 code = ngx_http_script_add_code(*sc->values,
1218 sizeof(ngx_http_script_full_name_code_t),
1219 &sc->main);
1220 if (code == NULL) {
1221 return NGX_ERROR;
1222 }
1223
1224 code->code = ngx_http_script_full_name_code;
1225 code->prefix = sc->conf_prefix;
1226
1227 return NGX_OK;
1228 }
1229
1230
1231 static size_t
1232 ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
1233 {
1234 ngx_http_script_full_name_code_t *code;
1235
1236 code = (ngx_http_script_full_name_code_t *) e->ip;
1237
1238 e->ip += sizeof(ngx_http_script_full_name_code_t);
1239
1240 return code->prefix ? sizeof(NGX_CONF_PREFIX) : ngx_cycle->root.len;
1241 }
1242
1243
1244 static void
1245 ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
1246 {
1247 ngx_http_script_full_name_code_t *code;
1248
1249 ngx_str_t value;
1250
1251 code = (ngx_http_script_full_name_code_t *) e->ip;
1252
1253 value.data = e->buf.data;
1254 value.len = e->pos - e->buf.data;
1255
1256 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->prefix)
1257 != NGX_OK)
1258 {
1259 e->ip = ngx_http_script_exit;
1260 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1261 return;
1262 }
1263
1264 e->buf = value;
1265
1266 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1267 "http script fullname: \"%V\"", &value);
1268
1269 e->ip += sizeof(ngx_http_script_full_name_code_t);
1270 }
1271
1272
9901273 void
9911274 ngx_http_script_return_code(ngx_http_script_engine_t *e)
9921275 {
5252 unsigned compile_args:1;
5353 unsigned complete_lengths:1;
5454 unsigned complete_values:1;
55 unsigned zero:1;
56 unsigned conf_prefix:1;
57 unsigned root_prefix:1;
58
5559 unsigned dup_capture:1;
56
5760 unsigned args:1;
5861 } ngx_http_script_compile_t;
5962
6063
64 typedef struct {
65 ngx_str_t value;
66 ngx_uint_t *flushes;
67 void *lengths;
68 void *values;
69 } ngx_http_complex_value_t;
70
71
72 typedef struct {
73 ngx_conf_t *cf;
74 ngx_str_t *value;
75 ngx_http_complex_value_t *complex_value;
76
77 unsigned zero:1;
78 unsigned conf_prefix:1;
79 unsigned root_prefix:1;
80 } ngx_http_compile_complex_value_t;
81
82
6183 typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
6284 typedef size_t (*ngx_http_script_len_code_pt) (ngx_http_script_engine_t *e);
6385
6486
6587 typedef struct {
66 ngx_http_script_code_pt code;
67 uintptr_t len;
88 ngx_http_script_code_pt code;
89 uintptr_t len;
6890 } ngx_http_script_copy_code_t;
6991
7092
7193 typedef struct {
72 ngx_http_script_code_pt code;
73 uintptr_t index;
94 ngx_http_script_code_pt code;
95 uintptr_t index;
7496 } ngx_http_script_var_code_t;
7597
7698
7799 typedef struct {
78 ngx_http_script_code_pt code;
79 ngx_http_set_variable_pt handler;
80 uintptr_t data;
100 ngx_http_script_code_pt code;
101 ngx_http_set_variable_pt handler;
102 uintptr_t data;
81103 } ngx_http_script_var_handler_code_t;
82104
83105
84106 typedef struct {
85 ngx_http_script_code_pt code;
86 uintptr_t n;
107 ngx_http_script_code_pt code;
108 uintptr_t n;
87109 } ngx_http_script_copy_capture_code_t;
88110
89111
90112 #if (NGX_PCRE)
91113
92114 typedef struct {
93 ngx_http_script_code_pt code;
94 ngx_regex_t *regex;
95 ngx_array_t *lengths;
96 uintptr_t size;
97 uintptr_t ncaptures;
98 uintptr_t status;
99 uintptr_t next;
100
101 uintptr_t test:1;
102 uintptr_t negative_test:1;
103 uintptr_t uri:1;
104 uintptr_t args:1;
115 ngx_http_script_code_pt code;
116 ngx_regex_t *regex;
117 ngx_array_t *lengths;
118 uintptr_t size;
119 uintptr_t ncaptures;
120 uintptr_t status;
121 uintptr_t next;
122
123 uintptr_t test:1;
124 uintptr_t negative_test:1;
125 uintptr_t uri:1;
126 uintptr_t args:1;
105127
106128 /* add the r->args to the new arguments */
107 uintptr_t add_args:1;
108
109 uintptr_t redirect:1;
110 uintptr_t break_cycle:1;
111
112 ngx_str_t name;
129 uintptr_t add_args:1;
130
131 uintptr_t redirect:1;
132 uintptr_t break_cycle:1;
133
134 ngx_str_t name;
113135 } ngx_http_script_regex_code_t;
114136
115137
116138 typedef struct {
117 ngx_http_script_code_pt code;
118
119 uintptr_t uri:1;
120 uintptr_t args:1;
139 ngx_http_script_code_pt code;
140
141 uintptr_t uri:1;
142 uintptr_t args:1;
121143
122144 /* add the r->args to the new arguments */
123 uintptr_t add_args:1;
124
125 uintptr_t redirect:1;
145 uintptr_t add_args:1;
146
147 uintptr_t redirect:1;
126148 } ngx_http_script_regex_end_code_t;
127149
128150 #endif
129151
130152
131153 typedef struct {
132 ngx_http_script_code_pt code;
133 uintptr_t status;
134 uintptr_t null;
154 ngx_http_script_code_pt code;
155 uintptr_t prefix;
156 } ngx_http_script_full_name_code_t;
157
158
159 typedef struct {
160 ngx_http_script_code_pt code;
161 uintptr_t status;
162 uintptr_t null;
135163 } ngx_http_script_return_code_t;
136164
137165
148176
149177
150178 typedef struct {
151 ngx_http_script_code_pt code;
152 uintptr_t op;
179 ngx_http_script_code_pt code;
180 uintptr_t op;
153181 } ngx_http_script_file_code_t;
154182
155183
156184 typedef struct {
157 ngx_http_script_code_pt code;
158 uintptr_t next;
159 void **loc_conf;
185 ngx_http_script_code_pt code;
186 uintptr_t next;
187 void **loc_conf;
160188 } ngx_http_script_if_code_t;
161189
162190
163191 typedef struct {
164 ngx_http_script_code_pt code;
165 ngx_array_t *lengths;
192 ngx_http_script_code_pt code;
193 ngx_array_t *lengths;
166194 } ngx_http_script_complex_value_code_t;
167195
168196
169197 typedef struct {
170 ngx_http_script_code_pt code;
171 uintptr_t value;
172 uintptr_t text_len;
173 uintptr_t text_data;
198 ngx_http_script_code_pt code;
199 uintptr_t value;
200 uintptr_t text_len;
201 uintptr_t text_data;
174202 } ngx_http_script_value_code_t;
175203
204
205 void ngx_http_scrip_flush_complex_value(ngx_http_request_t *r,
206 ngx_http_complex_value_t *val);
207 ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
208 ngx_http_complex_value_t *val, ngx_str_t *value);
209 ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
176210
177211 ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
178212 ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);