Mercurial > hg > nginx-quic
comparison src/http/ngx_http_script.c @ 2587:8afc4df77ee8
ngx_http_script_flush_complex_value()
ngx_http_complex_value()
ngx_http_compile_complex_value()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 22 Mar 2009 09:36:51 +0000 |
parents | 2dcbcfc1a8d1 |
children | 2f4a3a4dfd34 |
comparison
equal
deleted
inserted
replaced
2586:41a965fba141 | 2587:8afc4df77ee8 |
---|---|
10 | 10 |
11 | 11 |
12 static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc); | 12 static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc); |
13 static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc); | 13 static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc); |
14 static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, | 14 static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, |
15 ngx_str_t *value); | 15 ngx_str_t *value, ngx_uint_t last); |
16 static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, | 16 static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, |
17 ngx_str_t *name); | 17 ngx_str_t *name); |
18 static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc); | 18 static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc); |
19 #if (NGX_PCRE) | 19 #if (NGX_PCRE) |
20 static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, | 20 static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, |
21 ngx_uint_t n); | 21 ngx_uint_t n); |
22 #endif | 22 #endif |
23 static ngx_int_t | |
24 ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc); | |
25 static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e); | |
26 static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e); | |
23 | 27 |
24 | 28 |
25 #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code | 29 #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code |
26 | 30 |
27 static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL; | 31 static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL; |
32 | |
33 | |
34 void | |
35 ngx_http_scrip_flush_complex_value(ngx_http_request_t *r, | |
36 ngx_http_complex_value_t *val) | |
37 { | |
38 ngx_uint_t *index; | |
39 | |
40 index = val->flushes; | |
41 | |
42 if (index) { | |
43 while (*index != (ngx_uint_t) -1) { | |
44 | |
45 if (r->variables[*index].no_cacheable) { | |
46 r->variables[*index].valid = 0; | |
47 r->variables[*index].not_found = 0; | |
48 } | |
49 | |
50 index++; | |
51 } | |
52 } | |
53 } | |
54 | |
55 | |
56 ngx_int_t | |
57 ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val, | |
58 ngx_str_t *value) | |
59 { | |
60 size_t len; | |
61 ngx_http_script_code_pt code; | |
62 ngx_http_script_len_code_pt lcode; | |
63 ngx_http_script_engine_t e; | |
64 | |
65 if (val->lengths == NULL) { | |
66 *value = val->value; | |
67 return NGX_OK; | |
68 } | |
69 | |
70 ngx_http_scrip_flush_complex_value(r, val); | |
71 | |
72 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
73 | |
74 e.ip = val->lengths; | |
75 e.request = r; | |
76 e.flushed = 1; | |
77 | |
78 len = 0; | |
79 | |
80 while (*(uintptr_t *) e.ip) { | |
81 lcode = *(ngx_http_script_len_code_pt *) e.ip; | |
82 len += lcode(&e); | |
83 } | |
84 | |
85 value->len = len; | |
86 value->data = ngx_pnalloc(r->pool, len); | |
87 if (value->data == NULL) { | |
88 return NGX_ERROR; | |
89 } | |
90 | |
91 e.ip = val->values; | |
92 e.pos = value->data; | |
93 e.buf = *value; | |
94 | |
95 while (*(uintptr_t *) e.ip) { | |
96 code = *(ngx_http_script_code_pt *) e.ip; | |
97 code((ngx_http_script_engine_t *) &e); | |
98 } | |
99 | |
100 *value = e.buf; | |
101 | |
102 return NGX_OK; | |
103 } | |
104 | |
105 | |
106 ngx_int_t | |
107 ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv) | |
108 { | |
109 ngx_str_t *v; | |
110 ngx_uint_t i, n, nv, nc; | |
111 ngx_array_t flushes, lengths, values, *pf, *pl, *pv; | |
112 ngx_http_script_compile_t sc; | |
113 | |
114 v = ccv->value; | |
115 | |
116 if (v->len == 0) { | |
117 ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter"); | |
118 return NGX_ERROR; | |
119 } | |
120 | |
121 ccv->complex_value->value = *v; | |
122 ccv->complex_value->flushes = NULL; | |
123 ccv->complex_value->lengths = NULL; | |
124 ccv->complex_value->values = NULL; | |
125 | |
126 nv = 0; | |
127 nc = 0; | |
128 | |
129 for (i = 0; i < v->len; i++) { | |
130 if (v->data[i] == '$') { | |
131 if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') { | |
132 nc++; | |
133 | |
134 } else { | |
135 nv++; | |
136 } | |
137 } | |
138 } | |
139 | |
140 if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) { | |
141 | |
142 if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) { | |
143 return NGX_ERROR; | |
144 } | |
145 | |
146 ccv->conf_prefix = 0; | |
147 ccv->root_prefix = 0; | |
148 } | |
149 | |
150 if (nv == 0 && nc == 0) { | |
151 return NGX_OK; | |
152 } | |
153 | |
154 n = nv + 1; | |
155 | |
156 if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t)) | |
157 != NGX_OK) | |
158 { | |
159 return NGX_ERROR; | |
160 } | |
161 | |
162 n = nv * (2 * sizeof(ngx_http_script_copy_code_t) | |
163 + sizeof(ngx_http_script_var_code_t)) | |
164 + sizeof(uintptr_t); | |
165 | |
166 if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) { | |
167 return NGX_ERROR; | |
168 } | |
169 | |
170 n = (nv * (2 * sizeof(ngx_http_script_copy_code_t) | |
171 + sizeof(ngx_http_script_var_code_t)) | |
172 + sizeof(uintptr_t) | |
173 + v->len | |
174 + sizeof(uintptr_t) - 1) | |
175 & ~(sizeof(uintptr_t) - 1); | |
176 | |
177 if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) { | |
178 return NGX_ERROR; | |
179 } | |
180 | |
181 pf = &flushes; | |
182 pl = &lengths; | |
183 pv = &values; | |
184 | |
185 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
186 | |
187 sc.cf = ccv->cf; | |
188 sc.source = v; | |
189 sc.flushes = &pf; | |
190 sc.lengths = &pl; | |
191 sc.values = &pv; | |
192 sc.complete_lengths = 1; | |
193 sc.complete_values = 1; | |
194 sc.zero = ccv->zero; | |
195 sc.conf_prefix = ccv->conf_prefix; | |
196 sc.root_prefix = ccv->root_prefix; | |
197 | |
198 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
199 return NGX_ERROR; | |
200 } | |
201 | |
202 if (flushes.nelts) { | |
203 ccv->complex_value->flushes = flushes.elts; | |
204 ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1; | |
205 } | |
206 | |
207 ccv->complex_value->lengths = lengths.elts; | |
208 ccv->complex_value->values = values.elts; | |
209 | |
210 return NGX_OK; | |
211 } | |
28 | 212 |
29 | 213 |
30 ngx_uint_t | 214 ngx_uint_t |
31 ngx_http_script_variables_count(ngx_str_t *value) | 215 ngx_http_script_variables_count(ngx_str_t *value) |
32 { | 216 { |
178 name.len++; | 362 name.len++; |
179 } | 363 } |
180 | 364 |
181 sc->size += name.len; | 365 sc->size += name.len; |
182 | 366 |
183 if (ngx_http_script_add_copy_code(sc, &name) != NGX_OK) { | 367 if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len)) |
368 != NGX_OK) | |
369 { | |
184 return NGX_ERROR; | 370 return NGX_ERROR; |
185 } | 371 } |
186 } | 372 } |
187 | 373 |
188 return ngx_http_script_done(sc); | 374 return ngx_http_script_done(sc); |
307 | 493 |
308 | 494 |
309 static ngx_int_t | 495 static ngx_int_t |
310 ngx_http_script_done(ngx_http_script_compile_t *sc) | 496 ngx_http_script_done(ngx_http_script_compile_t *sc) |
311 { | 497 { |
498 ngx_str_t zero; | |
312 uintptr_t *code; | 499 uintptr_t *code; |
500 | |
501 if (sc->zero) { | |
502 | |
503 zero.len = 1; | |
504 zero.data = (u_char *) "\0"; | |
505 | |
506 if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) { | |
507 return NGX_ERROR; | |
508 } | |
509 } | |
510 | |
511 if (sc->conf_prefix || sc->root_prefix) { | |
512 if (ngx_http_script_add_full_name_code(sc) != NGX_OK) { | |
513 return NGX_ERROR; | |
514 } | |
515 } | |
313 | 516 |
314 if (sc->complete_lengths) { | 517 if (sc->complete_lengths) { |
315 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL); | 518 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL); |
316 if (code == NULL) { | 519 if (code == NULL) { |
317 return NGX_ERROR; | 520 return NGX_ERROR; |
371 return new; | 574 return new; |
372 } | 575 } |
373 | 576 |
374 | 577 |
375 static ngx_int_t | 578 static ngx_int_t |
376 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value) | 579 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value, |
377 { | 580 ngx_uint_t last) |
378 size_t size; | 581 { |
582 u_char *p; | |
583 size_t size, len, zero; | |
379 ngx_http_script_copy_code_t *code; | 584 ngx_http_script_copy_code_t *code; |
585 | |
586 zero = (sc->zero && last); | |
587 len = value->len + zero; | |
380 | 588 |
381 code = ngx_http_script_add_code(*sc->lengths, | 589 code = ngx_http_script_add_code(*sc->lengths, |
382 sizeof(ngx_http_script_copy_code_t), NULL); | 590 sizeof(ngx_http_script_copy_code_t), NULL); |
383 if (code == NULL) { | 591 if (code == NULL) { |
384 return NGX_ERROR; | 592 return NGX_ERROR; |
385 } | 593 } |
386 | 594 |
387 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; | 595 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
388 code->len = value->len; | 596 code->len = len; |
389 | 597 |
390 size = (sizeof(ngx_http_script_copy_code_t) + value->len | 598 size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1) |
391 + sizeof(uintptr_t) - 1) | |
392 & ~(sizeof(uintptr_t) - 1); | 599 & ~(sizeof(uintptr_t) - 1); |
393 | 600 |
394 code = ngx_http_script_add_code(*sc->values, size, &sc->main); | 601 code = ngx_http_script_add_code(*sc->values, size, &sc->main); |
395 if (code == NULL) { | 602 if (code == NULL) { |
396 return NGX_ERROR; | 603 return NGX_ERROR; |
397 } | 604 } |
398 | 605 |
399 code->code = ngx_http_script_copy_code; | 606 code->code = ngx_http_script_copy_code; |
400 code->len = value->len; | 607 code->len = len; |
401 | 608 |
402 ngx_memcpy((u_char *) code + sizeof(ngx_http_script_copy_code_t), | 609 p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t), |
403 value->data, value->len); | 610 value->data, value->len); |
611 | |
612 if (zero) { | |
613 *p = '\0'; | |
614 sc->zero = 0; | |
615 } | |
404 | 616 |
405 return NGX_OK; | 617 return NGX_OK; |
406 } | 618 } |
407 | 619 |
408 | 620 |
986 } | 1198 } |
987 | 1199 |
988 #endif | 1200 #endif |
989 | 1201 |
990 | 1202 |
1203 static ngx_int_t | |
1204 ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc) | |
1205 { | |
1206 ngx_http_script_full_name_code_t *code; | |
1207 | |
1208 code = ngx_http_script_add_code(*sc->lengths, | |
1209 sizeof(ngx_http_script_full_name_code_t), | |
1210 NULL); | |
1211 if (code == NULL) { | |
1212 return NGX_ERROR; | |
1213 } | |
1214 | |
1215 code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code; | |
1216 code->prefix = sc->conf_prefix; | |
1217 | |
1218 code = ngx_http_script_add_code(*sc->values, | |
1219 sizeof(ngx_http_script_full_name_code_t), | |
1220 &sc->main); | |
1221 if (code == NULL) { | |
1222 return NGX_ERROR; | |
1223 } | |
1224 | |
1225 code->code = ngx_http_script_full_name_code; | |
1226 code->prefix = sc->conf_prefix; | |
1227 | |
1228 return NGX_OK; | |
1229 } | |
1230 | |
1231 | |
1232 static size_t | |
1233 ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e) | |
1234 { | |
1235 ngx_http_script_full_name_code_t *code; | |
1236 | |
1237 code = (ngx_http_script_full_name_code_t *) e->ip; | |
1238 | |
1239 e->ip += sizeof(ngx_http_script_full_name_code_t); | |
1240 | |
1241 return code->prefix ? sizeof(NGX_CONF_PREFIX) : ngx_cycle->root.len; | |
1242 } | |
1243 | |
1244 | |
1245 static void | |
1246 ngx_http_script_full_name_code(ngx_http_script_engine_t *e) | |
1247 { | |
1248 ngx_http_script_full_name_code_t *code; | |
1249 | |
1250 ngx_str_t value; | |
1251 | |
1252 code = (ngx_http_script_full_name_code_t *) e->ip; | |
1253 | |
1254 value.data = e->buf.data; | |
1255 value.len = e->pos - e->buf.data; | |
1256 | |
1257 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->prefix) | |
1258 != NGX_OK) | |
1259 { | |
1260 e->ip = ngx_http_script_exit; | |
1261 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1262 return; | |
1263 } | |
1264 | |
1265 e->buf = value; | |
1266 | |
1267 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
1268 "http script fullname: \"%V\"", &value); | |
1269 | |
1270 e->ip += sizeof(ngx_http_script_full_name_code_t); | |
1271 } | |
1272 | |
1273 | |
991 void | 1274 void |
992 ngx_http_script_return_code(ngx_http_script_engine_t *e) | 1275 ngx_http_script_return_code(ngx_http_script_engine_t *e) |
993 { | 1276 { |
994 ngx_http_script_return_code_t *code; | 1277 ngx_http_script_return_code_t *code; |
995 | 1278 |