Mercurial > hg > nginx
comparison src/http/ngx_http_script.c @ 2577:2dcbcfc1a8d1
split ngx_http_script_compile()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 18 Mar 2009 14:42:06 +0000 |
parents | 912ce4113f21 |
children | 8afc4df77ee8 |
comparison
equal
deleted
inserted
replaced
2576:f4bed862cc9b | 2577:2dcbcfc1a8d1 |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
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); | |
14 static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, | |
15 ngx_str_t *value); | |
16 static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, | |
17 ngx_str_t *name); | |
18 static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc); | |
19 #if (NGX_PCRE) | |
20 static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, | |
21 ngx_uint_t n); | |
22 #endif | |
23 | |
24 | |
12 #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code | 25 #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code |
13 | 26 |
14 static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL; | 27 static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL; |
15 | 28 |
16 | 29 |
30 | 43 |
31 | 44 |
32 ngx_int_t | 45 ngx_int_t |
33 ngx_http_script_compile(ngx_http_script_compile_t *sc) | 46 ngx_http_script_compile(ngx_http_script_compile_t *sc) |
34 { | 47 { |
35 u_char ch; | 48 u_char ch; |
36 size_t size; | 49 ngx_str_t name; |
37 ngx_int_t index, *p; | 50 ngx_uint_t i, bracket; |
38 ngx_str_t name; | 51 |
39 uintptr_t *code; | 52 if (ngx_http_script_init_arrays(sc) != NGX_OK) { |
40 ngx_uint_t i, n, bracket; | 53 return NGX_ERROR; |
41 ngx_http_script_var_code_t *var_code; | 54 } |
42 ngx_http_script_copy_code_t *copy; | 55 |
56 for (i = 0; i < sc->source->len; /* void */ ) { | |
57 | |
58 name.len = 0; | |
59 | |
60 if (sc->source->data[i] == '$') { | |
61 | |
62 if (++i == sc->source->len) { | |
63 goto invalid_variable; | |
64 } | |
65 | |
43 #if (NGX_PCRE) | 66 #if (NGX_PCRE) |
44 ngx_http_script_copy_capture_code_t *copy_capture; | 67 { |
68 ngx_uint_t n; | |
69 | |
70 /* NGX_HTTP_MAX_CAPTURES is 9 */ | |
71 | |
72 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { | |
73 | |
74 n = sc->source->data[i] - '0'; | |
75 | |
76 if (sc->captures_mask & (1 << n)) { | |
77 sc->dup_capture = 1; | |
78 } | |
79 | |
80 sc->captures_mask |= 1 << n; | |
81 | |
82 if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) { | |
83 return NGX_ERROR; | |
84 } | |
85 | |
86 i++; | |
87 | |
88 continue; | |
89 } | |
90 } | |
45 #endif | 91 #endif |
92 | |
93 if (sc->source->data[i] == '{') { | |
94 bracket = 1; | |
95 | |
96 if (++i == sc->source->len) { | |
97 goto invalid_variable; | |
98 } | |
99 | |
100 name.data = &sc->source->data[i]; | |
101 | |
102 } else { | |
103 bracket = 0; | |
104 name.data = &sc->source->data[i]; | |
105 } | |
106 | |
107 for ( /* void */ ; i < sc->source->len; i++, name.len++) { | |
108 ch = sc->source->data[i]; | |
109 | |
110 if (ch == '}' && bracket) { | |
111 i++; | |
112 bracket = 0; | |
113 break; | |
114 } | |
115 | |
116 if ((ch >= 'A' && ch <= 'Z') | |
117 || (ch >= 'a' && ch <= 'z') | |
118 || (ch >= '0' && ch <= '9') | |
119 || ch == '_') | |
120 { | |
121 continue; | |
122 } | |
123 | |
124 break; | |
125 } | |
126 | |
127 if (bracket) { | |
128 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, | |
129 "the closing bracket in \"%V\" " | |
130 "variable is missing", &name); | |
131 return NGX_ERROR; | |
132 } | |
133 | |
134 if (name.len == 0) { | |
135 goto invalid_variable; | |
136 } | |
137 | |
138 sc->variables++; | |
139 | |
140 if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) { | |
141 return NGX_ERROR; | |
142 } | |
143 | |
144 continue; | |
145 } | |
146 | |
147 if (sc->source->data[i] == '?' && sc->compile_args) { | |
148 sc->args = 1; | |
149 sc->compile_args = 0; | |
150 | |
151 if (ngx_http_script_add_args_code(sc) != NGX_OK) { | |
152 return NGX_ERROR; | |
153 } | |
154 | |
155 i++; | |
156 | |
157 continue; | |
158 } | |
159 | |
160 name.data = &sc->source->data[i]; | |
161 | |
162 while (i < sc->source->len) { | |
163 | |
164 if (sc->source->data[i] == '$') { | |
165 break; | |
166 } | |
167 | |
168 if (sc->source->data[i] == '?') { | |
169 | |
170 sc->args = 1; | |
171 | |
172 if (sc->compile_args) { | |
173 break; | |
174 } | |
175 } | |
176 | |
177 i++; | |
178 name.len++; | |
179 } | |
180 | |
181 sc->size += name.len; | |
182 | |
183 if (ngx_http_script_add_copy_code(sc, &name) != NGX_OK) { | |
184 return NGX_ERROR; | |
185 } | |
186 } | |
187 | |
188 return ngx_http_script_done(sc); | |
189 | |
190 invalid_variable: | |
191 | |
192 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name"); | |
193 | |
194 return NGX_ERROR; | |
195 } | |
196 | |
197 | |
198 u_char * | |
199 ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, | |
200 void *code_lengths, size_t len, void *code_values) | |
201 { | |
202 ngx_uint_t i; | |
203 ngx_http_script_code_pt code; | |
204 ngx_http_script_len_code_pt lcode; | |
205 ngx_http_script_engine_t e; | |
206 ngx_http_core_main_conf_t *cmcf; | |
207 | |
208 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
209 | |
210 for (i = 0; i < cmcf->variables.nelts; i++) { | |
211 if (r->variables[i].no_cacheable) { | |
212 r->variables[i].valid = 0; | |
213 r->variables[i].not_found = 0; | |
214 } | |
215 } | |
216 | |
217 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
218 | |
219 e.ip = code_lengths; | |
220 e.request = r; | |
221 e.flushed = 1; | |
222 | |
223 while (*(uintptr_t *) e.ip) { | |
224 lcode = *(ngx_http_script_len_code_pt *) e.ip; | |
225 len += lcode(&e); | |
226 } | |
227 | |
228 | |
229 value->len = len; | |
230 value->data = ngx_pnalloc(r->pool, len); | |
231 if (value->data == NULL) { | |
232 return NULL; | |
233 } | |
234 | |
235 e.ip = code_values; | |
236 e.pos = value->data; | |
237 | |
238 while (*(uintptr_t *) e.ip) { | |
239 code = *(ngx_http_script_code_pt *) e.ip; | |
240 code((ngx_http_script_engine_t *) &e); | |
241 } | |
242 | |
243 return e.pos; | |
244 } | |
245 | |
246 | |
247 void | |
248 ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r, | |
249 ngx_array_t *indices) | |
250 { | |
251 ngx_uint_t n, *index; | |
252 | |
253 if (indices) { | |
254 index = indices->elts; | |
255 for (n = 0; n < indices->nelts; n++) { | |
256 if (r->variables[index[n]].no_cacheable) { | |
257 r->variables[index[n]].valid = 0; | |
258 r->variables[index[n]].not_found = 0; | |
259 } | |
260 } | |
261 } | |
262 } | |
263 | |
264 | |
265 static ngx_int_t | |
266 ngx_http_script_init_arrays(ngx_http_script_compile_t *sc) | |
267 { | |
268 ngx_uint_t n; | |
46 | 269 |
47 if (sc->flushes && *sc->flushes == NULL) { | 270 if (sc->flushes && *sc->flushes == NULL) { |
48 n = sc->variables ? sc->variables : 1; | 271 n = sc->variables ? sc->variables : 1; |
49 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); | 272 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); |
50 if (*sc->flushes == NULL) { | 273 if (*sc->flushes == NULL) { |
51 return NGX_ERROR; | 274 return NGX_ERROR; |
52 } | 275 } |
53 } | 276 } |
54 | 277 |
55 | |
56 if (*sc->lengths == NULL) { | 278 if (*sc->lengths == NULL) { |
57 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) | 279 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) |
58 + sizeof(ngx_http_script_var_code_t)) | 280 + sizeof(ngx_http_script_var_code_t)) |
59 + sizeof(uintptr_t); | 281 + sizeof(uintptr_t); |
60 | 282 |
61 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1); | 283 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1); |
62 if (*sc->lengths == NULL) { | 284 if (*sc->lengths == NULL) { |
63 return NGX_ERROR; | 285 return NGX_ERROR; |
64 } | 286 } |
65 } | 287 } |
66 | |
67 | 288 |
68 if (*sc->values == NULL) { | 289 if (*sc->values == NULL) { |
69 n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) | 290 n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) |
70 + sizeof(ngx_http_script_var_code_t)) | 291 + sizeof(ngx_http_script_var_code_t)) |
71 + sizeof(uintptr_t) | 292 + sizeof(uintptr_t) |
79 } | 300 } |
80 } | 301 } |
81 | 302 |
82 sc->variables = 0; | 303 sc->variables = 0; |
83 | 304 |
84 for (i = 0; i < sc->source->len; /* void */ ) { | 305 return NGX_OK; |
85 | 306 } |
86 name.len = 0; | 307 |
87 | 308 |
88 if (sc->source->data[i] == '$') { | 309 static ngx_int_t |
89 | 310 ngx_http_script_done(ngx_http_script_compile_t *sc) |
90 if (++i == sc->source->len) { | 311 { |
91 goto invalid_variable; | 312 uintptr_t *code; |
92 } | |
93 | |
94 #if (NGX_PCRE) | |
95 | |
96 /* NGX_HTTP_MAX_CAPTURES is 9 */ | |
97 | |
98 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { | |
99 | |
100 n = sc->source->data[i] - '0'; | |
101 | |
102 if (sc->captures_mask & (1 << n)) { | |
103 sc->dup_capture = 1; | |
104 } | |
105 | |
106 sc->captures_mask |= 1 << n; | |
107 | |
108 copy_capture = ngx_http_script_add_code(*sc->lengths, | |
109 sizeof(ngx_http_script_copy_capture_code_t), | |
110 NULL); | |
111 if (copy_capture == NULL) { | |
112 return NGX_ERROR; | |
113 } | |
114 | |
115 copy_capture->code = (ngx_http_script_code_pt) | |
116 ngx_http_script_copy_capture_len_code; | |
117 copy_capture->n = 2 * n; | |
118 | |
119 | |
120 copy_capture = ngx_http_script_add_code(*sc->values, | |
121 sizeof(ngx_http_script_copy_capture_code_t), | |
122 &sc->main); | |
123 if (copy_capture == NULL) { | |
124 return NGX_ERROR; | |
125 } | |
126 | |
127 copy_capture->code = ngx_http_script_copy_capture_code; | |
128 copy_capture->n = 2 * n; | |
129 | |
130 if (sc->ncaptures < n) { | |
131 sc->ncaptures = n; | |
132 } | |
133 | |
134 i++; | |
135 | |
136 continue; | |
137 } | |
138 | |
139 #endif | |
140 | |
141 if (sc->source->data[i] == '{') { | |
142 bracket = 1; | |
143 | |
144 if (++i == sc->source->len) { | |
145 goto invalid_variable; | |
146 } | |
147 | |
148 name.data = &sc->source->data[i]; | |
149 | |
150 } else { | |
151 bracket = 0; | |
152 name.data = &sc->source->data[i]; | |
153 } | |
154 | |
155 for ( /* void */ ; i < sc->source->len; i++, name.len++) { | |
156 ch = sc->source->data[i]; | |
157 | |
158 if (ch == '}' && bracket) { | |
159 i++; | |
160 bracket = 0; | |
161 break; | |
162 } | |
163 | |
164 if ((ch >= 'A' && ch <= 'Z') | |
165 || (ch >= 'a' && ch <= 'z') | |
166 || (ch >= '0' && ch <= '9') | |
167 || ch == '_') | |
168 { | |
169 continue; | |
170 } | |
171 | |
172 break; | |
173 } | |
174 | |
175 if (bracket) { | |
176 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, | |
177 "the closing bracket in \"%V\" " | |
178 "variable is missing", &name); | |
179 return NGX_ERROR; | |
180 } | |
181 | |
182 if (name.len == 0) { | |
183 goto invalid_variable; | |
184 } | |
185 | |
186 sc->variables++; | |
187 | |
188 index = ngx_http_get_variable_index(sc->cf, &name); | |
189 | |
190 if (index == NGX_ERROR) { | |
191 return NGX_ERROR; | |
192 } | |
193 | |
194 if (sc->flushes) { | |
195 p = ngx_array_push(*sc->flushes); | |
196 if (p == NULL) { | |
197 return NGX_ERROR; | |
198 } | |
199 | |
200 *p = index; | |
201 } | |
202 | |
203 var_code = ngx_http_script_add_code(*sc->lengths, | |
204 sizeof(ngx_http_script_var_code_t), | |
205 NULL); | |
206 if (var_code == NULL) { | |
207 return NGX_ERROR; | |
208 } | |
209 | |
210 var_code->code = (ngx_http_script_code_pt) | |
211 ngx_http_script_copy_var_len_code; | |
212 var_code->index = (uintptr_t) index; | |
213 | |
214 | |
215 var_code = ngx_http_script_add_code(*sc->values, | |
216 sizeof(ngx_http_script_var_code_t), | |
217 &sc->main); | |
218 if (var_code == NULL) { | |
219 return NGX_ERROR; | |
220 } | |
221 | |
222 var_code->code = ngx_http_script_copy_var_code; | |
223 var_code->index = (uintptr_t) index; | |
224 | |
225 continue; | |
226 } | |
227 | |
228 if (sc->source->data[i] == '?' && sc->compile_args) { | |
229 sc->args = 1; | |
230 sc->compile_args = 0; | |
231 | |
232 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), | |
233 NULL); | |
234 if (code == NULL) { | |
235 return NGX_ERROR; | |
236 } | |
237 | |
238 *code = (uintptr_t) ngx_http_script_mark_args_code; | |
239 | |
240 code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), | |
241 &sc->main); | |
242 if (code == NULL) { | |
243 return NGX_ERROR; | |
244 } | |
245 | |
246 *code = (uintptr_t) ngx_http_script_start_args_code; | |
247 | |
248 i++; | |
249 | |
250 continue; | |
251 } | |
252 | |
253 name.data = &sc->source->data[i]; | |
254 | |
255 while (i < sc->source->len) { | |
256 | |
257 if (sc->source->data[i] == '$') { | |
258 break; | |
259 } | |
260 | |
261 if (sc->source->data[i] == '?') { | |
262 | |
263 sc->args = 1; | |
264 | |
265 if (sc->compile_args) { | |
266 break; | |
267 } | |
268 } | |
269 | |
270 i++; | |
271 name.len++; | |
272 } | |
273 | |
274 sc->size += name.len; | |
275 | |
276 copy = ngx_http_script_add_code(*sc->lengths, | |
277 sizeof(ngx_http_script_copy_code_t), | |
278 NULL); | |
279 if (copy == NULL) { | |
280 return NGX_ERROR; | |
281 } | |
282 | |
283 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; | |
284 copy->len = name.len; | |
285 | |
286 size = (sizeof(ngx_http_script_copy_code_t) + name.len | |
287 + sizeof(uintptr_t) - 1) | |
288 & ~(sizeof(uintptr_t) - 1); | |
289 | |
290 copy = ngx_http_script_add_code(*sc->values, size, &sc->main); | |
291 if (copy == NULL) { | |
292 return NGX_ERROR; | |
293 } | |
294 | |
295 copy->code = ngx_http_script_copy_code; | |
296 copy->len = name.len; | |
297 | |
298 ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t), | |
299 name.data, name.len); | |
300 } | |
301 | 313 |
302 if (sc->complete_lengths) { | 314 if (sc->complete_lengths) { |
303 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL); | 315 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL); |
304 if (code == NULL) { | 316 if (code == NULL) { |
305 return NGX_ERROR; | 317 return NGX_ERROR; |
317 | 329 |
318 *code = (uintptr_t) NULL; | 330 *code = (uintptr_t) NULL; |
319 } | 331 } |
320 | 332 |
321 return NGX_OK; | 333 return NGX_OK; |
322 | |
323 invalid_variable: | |
324 | |
325 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name"); | |
326 | |
327 return NGX_ERROR; | |
328 } | |
329 | |
330 | |
331 u_char * | |
332 ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, | |
333 void *code_lengths, size_t len, void *code_values) | |
334 { | |
335 ngx_uint_t i; | |
336 ngx_http_script_code_pt code; | |
337 ngx_http_script_len_code_pt lcode; | |
338 ngx_http_script_engine_t e; | |
339 ngx_http_core_main_conf_t *cmcf; | |
340 | |
341 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
342 | |
343 for (i = 0; i < cmcf->variables.nelts; i++) { | |
344 if (r->variables[i].no_cacheable) { | |
345 r->variables[i].valid = 0; | |
346 r->variables[i].not_found = 0; | |
347 } | |
348 } | |
349 | |
350 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
351 | |
352 e.ip = code_lengths; | |
353 e.request = r; | |
354 e.flushed = 1; | |
355 | |
356 while (*(uintptr_t *) e.ip) { | |
357 lcode = *(ngx_http_script_len_code_pt *) e.ip; | |
358 len += lcode(&e); | |
359 } | |
360 | |
361 | |
362 value->len = len; | |
363 value->data = ngx_pnalloc(r->pool, len); | |
364 if (value->data == NULL) { | |
365 return NULL; | |
366 } | |
367 | |
368 e.ip = code_values; | |
369 e.pos = value->data; | |
370 | |
371 while (*(uintptr_t *) e.ip) { | |
372 code = *(ngx_http_script_code_pt *) e.ip; | |
373 code((ngx_http_script_engine_t *) &e); | |
374 } | |
375 | |
376 return e.pos; | |
377 } | |
378 | |
379 | |
380 void | |
381 ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r, | |
382 ngx_array_t *indices) | |
383 { | |
384 ngx_uint_t n, *index; | |
385 | |
386 if (indices) { | |
387 index = indices->elts; | |
388 for (n = 0; n < indices->nelts; n++) { | |
389 if (r->variables[index[n]].no_cacheable) { | |
390 r->variables[index[n]].valid = 0; | |
391 r->variables[index[n]].not_found = 0; | |
392 } | |
393 } | |
394 } | |
395 } | 334 } |
396 | 335 |
397 | 336 |
398 void * | 337 void * |
399 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) | 338 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) |
431 | 370 |
432 return new; | 371 return new; |
433 } | 372 } |
434 | 373 |
435 | 374 |
375 static ngx_int_t | |
376 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value) | |
377 { | |
378 size_t size; | |
379 ngx_http_script_copy_code_t *code; | |
380 | |
381 code = ngx_http_script_add_code(*sc->lengths, | |
382 sizeof(ngx_http_script_copy_code_t), NULL); | |
383 if (code == NULL) { | |
384 return NGX_ERROR; | |
385 } | |
386 | |
387 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; | |
388 code->len = value->len; | |
389 | |
390 size = (sizeof(ngx_http_script_copy_code_t) + value->len | |
391 + sizeof(uintptr_t) - 1) | |
392 & ~(sizeof(uintptr_t) - 1); | |
393 | |
394 code = ngx_http_script_add_code(*sc->values, size, &sc->main); | |
395 if (code == NULL) { | |
396 return NGX_ERROR; | |
397 } | |
398 | |
399 code->code = ngx_http_script_copy_code; | |
400 code->len = value->len; | |
401 | |
402 ngx_memcpy((u_char *) code + sizeof(ngx_http_script_copy_code_t), | |
403 value->data, value->len); | |
404 | |
405 return NGX_OK; | |
406 } | |
407 | |
408 | |
436 size_t | 409 size_t |
437 ngx_http_script_copy_len_code(ngx_http_script_engine_t *e) | 410 ngx_http_script_copy_len_code(ngx_http_script_engine_t *e) |
438 { | 411 { |
439 ngx_http_script_copy_code_t *code; | 412 ngx_http_script_copy_code_t *code; |
440 | 413 |
467 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 440 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
468 "http script copy: \"%*s\"", e->pos - p, p); | 441 "http script copy: \"%*s\"", e->pos - p, p); |
469 } | 442 } |
470 | 443 |
471 | 444 |
445 static ngx_int_t | |
446 ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name) | |
447 { | |
448 ngx_int_t index, *p; | |
449 ngx_http_script_var_code_t *code; | |
450 | |
451 index = ngx_http_get_variable_index(sc->cf, name); | |
452 | |
453 if (index == NGX_ERROR) { | |
454 return NGX_ERROR; | |
455 } | |
456 | |
457 if (sc->flushes) { | |
458 p = ngx_array_push(*sc->flushes); | |
459 if (p == NULL) { | |
460 return NGX_ERROR; | |
461 } | |
462 | |
463 *p = index; | |
464 } | |
465 | |
466 code = ngx_http_script_add_code(*sc->lengths, | |
467 sizeof(ngx_http_script_var_code_t), NULL); | |
468 if (code == NULL) { | |
469 return NGX_ERROR; | |
470 } | |
471 | |
472 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_var_len_code; | |
473 code->index = (uintptr_t) index; | |
474 | |
475 code = ngx_http_script_add_code(*sc->values, | |
476 sizeof(ngx_http_script_var_code_t), | |
477 &sc->main); | |
478 if (code == NULL) { | |
479 return NGX_ERROR; | |
480 } | |
481 | |
482 code->code = ngx_http_script_copy_var_code; | |
483 code->index = (uintptr_t) index; | |
484 | |
485 return NGX_OK; | |
486 } | |
487 | |
488 | |
472 size_t | 489 size_t |
473 ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e) | 490 ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e) |
474 { | 491 { |
475 ngx_http_variable_value_t *value; | 492 ngx_http_variable_value_t *value; |
476 ngx_http_script_var_code_t *code; | 493 ngx_http_script_var_code_t *code; |
521 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, | 538 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, |
522 e->request->connection->log, 0, | 539 e->request->connection->log, 0, |
523 "http script var: \"%*s\"", e->pos - p, p); | 540 "http script var: \"%*s\"", e->pos - p, p); |
524 } | 541 } |
525 } | 542 } |
543 } | |
544 | |
545 | |
546 static ngx_int_t | |
547 ngx_http_script_add_args_code(ngx_http_script_compile_t *sc) | |
548 { | |
549 uintptr_t *code; | |
550 | |
551 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL); | |
552 if (code == NULL) { | |
553 return NGX_ERROR; | |
554 } | |
555 | |
556 *code = (uintptr_t) ngx_http_script_mark_args_code; | |
557 | |
558 code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main); | |
559 if (code == NULL) { | |
560 return NGX_ERROR; | |
561 } | |
562 | |
563 *code = (uintptr_t) ngx_http_script_start_args_code; | |
564 | |
565 return NGX_OK; | |
526 } | 566 } |
527 | 567 |
528 | 568 |
529 size_t | 569 size_t |
530 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e) | 570 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e) |
828 return; | 868 return; |
829 } | 869 } |
830 } | 870 } |
831 | 871 |
832 e->ip += sizeof(ngx_http_script_regex_end_code_t); | 872 e->ip += sizeof(ngx_http_script_regex_end_code_t); |
873 } | |
874 | |
875 | |
876 static ngx_int_t | |
877 ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n) | |
878 { | |
879 ngx_http_script_copy_capture_code_t *code; | |
880 | |
881 code = ngx_http_script_add_code(*sc->lengths, | |
882 sizeof(ngx_http_script_copy_capture_code_t), | |
883 NULL); | |
884 if (code == NULL) { | |
885 return NGX_ERROR; | |
886 } | |
887 | |
888 code->code = (ngx_http_script_code_pt) | |
889 ngx_http_script_copy_capture_len_code; | |
890 code->n = 2 * n; | |
891 | |
892 | |
893 code = ngx_http_script_add_code(*sc->values, | |
894 sizeof(ngx_http_script_copy_capture_code_t), | |
895 &sc->main); | |
896 if (code == NULL) { | |
897 return NGX_ERROR; | |
898 } | |
899 | |
900 code->code = ngx_http_script_copy_capture_code; | |
901 code->n = 2 * n; | |
902 | |
903 if (sc->ncaptures < n) { | |
904 sc->ncaptures = n; | |
905 } | |
906 | |
907 return NGX_OK; | |
833 } | 908 } |
834 | 909 |
835 | 910 |
836 size_t | 911 size_t |
837 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) | 912 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) |