comparison src/http/ngx_http_script.c @ 464:c8cfb6c462ef NGINX_0_7_44

nginx 0.7.44 *) Feature: the ngx_http_proxy_module preliminary cache support. *) Feature: the --with-pcre option in the configure. *) Feature: the "try_files" directive is now allowed on the server block level. *) Bugfix: the "try_files" directive handled incorrectly a query string in a fallback parameter. *) Bugfix: the "try_files" directive might test incorrectly directories. *) Bugfix: if there is the single server for given address:port pair, then captures in regular expressions in a "server_name" directive did not work.
author Igor Sysoev <http://sysoev.ru>
date Mon, 23 Mar 2009 00:00:00 +0300
parents ca8f7f6cab16
children 56baf312c1b5
comparison
equal deleted inserted replaced
463:51cb914e6d3a 464:c8cfb6c462ef
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, ngx_uint_t last);
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 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);
27
28
12 #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
13 30
14 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 }
15 212
16 213
17 ngx_uint_t 214 ngx_uint_t
18 ngx_http_script_variables_count(ngx_str_t *value) 215 ngx_http_script_variables_count(ngx_str_t *value)
19 { 216 {
30 227
31 228
32 ngx_int_t 229 ngx_int_t
33 ngx_http_script_compile(ngx_http_script_compile_t *sc) 230 ngx_http_script_compile(ngx_http_script_compile_t *sc)
34 { 231 {
35 u_char ch; 232 u_char ch;
36 size_t size; 233 ngx_str_t name;
37 ngx_int_t index, *p; 234 ngx_uint_t i, bracket;
38 ngx_str_t name; 235
39 uintptr_t *code; 236 if (ngx_http_script_init_arrays(sc) != NGX_OK) {
40 ngx_uint_t i, n, bracket; 237 return NGX_ERROR;
41 ngx_http_script_var_code_t *var_code; 238 }
42 ngx_http_script_copy_code_t *copy; 239
240 for (i = 0; i < sc->source->len; /* void */ ) {
241
242 name.len = 0;
243
244 if (sc->source->data[i] == '$') {
245
246 if (++i == sc->source->len) {
247 goto invalid_variable;
248 }
249
43 #if (NGX_PCRE) 250 #if (NGX_PCRE)
44 ngx_http_script_copy_capture_code_t *copy_capture; 251 {
252 ngx_uint_t n;
253
254 /* NGX_HTTP_MAX_CAPTURES is 9 */
255
256 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
257
258 n = sc->source->data[i] - '0';
259
260 if (sc->captures_mask & (1 << n)) {
261 sc->dup_capture = 1;
262 }
263
264 sc->captures_mask |= 1 << n;
265
266 if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
267 return NGX_ERROR;
268 }
269
270 i++;
271
272 continue;
273 }
274 }
45 #endif 275 #endif
276
277 if (sc->source->data[i] == '{') {
278 bracket = 1;
279
280 if (++i == sc->source->len) {
281 goto invalid_variable;
282 }
283
284 name.data = &sc->source->data[i];
285
286 } else {
287 bracket = 0;
288 name.data = &sc->source->data[i];
289 }
290
291 for ( /* void */ ; i < sc->source->len; i++, name.len++) {
292 ch = sc->source->data[i];
293
294 if (ch == '}' && bracket) {
295 i++;
296 bracket = 0;
297 break;
298 }
299
300 if ((ch >= 'A' && ch <= 'Z')
301 || (ch >= 'a' && ch <= 'z')
302 || (ch >= '0' && ch <= '9')
303 || ch == '_')
304 {
305 continue;
306 }
307
308 break;
309 }
310
311 if (bracket) {
312 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
313 "the closing bracket in \"%V\" "
314 "variable is missing", &name);
315 return NGX_ERROR;
316 }
317
318 if (name.len == 0) {
319 goto invalid_variable;
320 }
321
322 sc->variables++;
323
324 if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
325 return NGX_ERROR;
326 }
327
328 continue;
329 }
330
331 if (sc->source->data[i] == '?' && sc->compile_args) {
332 sc->args = 1;
333 sc->compile_args = 0;
334
335 if (ngx_http_script_add_args_code(sc) != NGX_OK) {
336 return NGX_ERROR;
337 }
338
339 i++;
340
341 continue;
342 }
343
344 name.data = &sc->source->data[i];
345
346 while (i < sc->source->len) {
347
348 if (sc->source->data[i] == '$') {
349 break;
350 }
351
352 if (sc->source->data[i] == '?') {
353
354 sc->args = 1;
355
356 if (sc->compile_args) {
357 break;
358 }
359 }
360
361 i++;
362 name.len++;
363 }
364
365 sc->size += name.len;
366
367 if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
368 != NGX_OK)
369 {
370 return NGX_ERROR;
371 }
372 }
373
374 return ngx_http_script_done(sc);
375
376 invalid_variable:
377
378 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
379
380 return NGX_ERROR;
381 }
382
383
384 u_char *
385 ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
386 void *code_lengths, size_t len, void *code_values)
387 {
388 ngx_uint_t i;
389 ngx_http_script_code_pt code;
390 ngx_http_script_len_code_pt lcode;
391 ngx_http_script_engine_t e;
392 ngx_http_core_main_conf_t *cmcf;
393
394 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
395
396 for (i = 0; i < cmcf->variables.nelts; i++) {
397 if (r->variables[i].no_cacheable) {
398 r->variables[i].valid = 0;
399 r->variables[i].not_found = 0;
400 }
401 }
402
403 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
404
405 e.ip = code_lengths;
406 e.request = r;
407 e.flushed = 1;
408
409 while (*(uintptr_t *) e.ip) {
410 lcode = *(ngx_http_script_len_code_pt *) e.ip;
411 len += lcode(&e);
412 }
413
414
415 value->len = len;
416 value->data = ngx_pnalloc(r->pool, len);
417 if (value->data == NULL) {
418 return NULL;
419 }
420
421 e.ip = code_values;
422 e.pos = value->data;
423
424 while (*(uintptr_t *) e.ip) {
425 code = *(ngx_http_script_code_pt *) e.ip;
426 code((ngx_http_script_engine_t *) &e);
427 }
428
429 return e.pos;
430 }
431
432
433 void
434 ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
435 ngx_array_t *indices)
436 {
437 ngx_uint_t n, *index;
438
439 if (indices) {
440 index = indices->elts;
441 for (n = 0; n < indices->nelts; n++) {
442 if (r->variables[index[n]].no_cacheable) {
443 r->variables[index[n]].valid = 0;
444 r->variables[index[n]].not_found = 0;
445 }
446 }
447 }
448 }
449
450
451 static ngx_int_t
452 ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
453 {
454 ngx_uint_t n;
46 455
47 if (sc->flushes && *sc->flushes == NULL) { 456 if (sc->flushes && *sc->flushes == NULL) {
48 n = sc->variables ? sc->variables : 1; 457 n = sc->variables ? sc->variables : 1;
49 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); 458 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
50 if (*sc->flushes == NULL) { 459 if (*sc->flushes == NULL) {
51 return NGX_ERROR; 460 return NGX_ERROR;
52 } 461 }
53 } 462 }
54 463
55
56 if (*sc->lengths == NULL) { 464 if (*sc->lengths == NULL) {
57 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) 465 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
58 + sizeof(ngx_http_script_var_code_t)) 466 + sizeof(ngx_http_script_var_code_t))
59 + sizeof(uintptr_t); 467 + sizeof(uintptr_t);
60 468
61 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1); 469 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
62 if (*sc->lengths == NULL) { 470 if (*sc->lengths == NULL) {
63 return NGX_ERROR; 471 return NGX_ERROR;
64 } 472 }
65 } 473 }
66
67 474
68 if (*sc->values == NULL) { 475 if (*sc->values == NULL) {
69 n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) 476 n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
70 + sizeof(ngx_http_script_var_code_t)) 477 + sizeof(ngx_http_script_var_code_t))
71 + sizeof(uintptr_t) 478 + sizeof(uintptr_t)
79 } 486 }
80 } 487 }
81 488
82 sc->variables = 0; 489 sc->variables = 0;
83 490
84 for (i = 0; i < sc->source->len; /* void */ ) { 491 return NGX_OK;
85 492 }
86 name.len = 0; 493
87 494
88 if (sc->source->data[i] == '$') { 495 static ngx_int_t
89 496 ngx_http_script_done(ngx_http_script_compile_t *sc)
90 if (++i == sc->source->len) { 497 {
91 goto invalid_variable; 498 ngx_str_t zero;
92 } 499 uintptr_t *code;
93 500
94 #if (NGX_PCRE) 501 if (sc->zero) {
95 502
96 /* NGX_HTTP_MAX_CAPTURES is 9 */ 503 zero.len = 1;
97 504 zero.data = (u_char *) "\0";
98 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { 505
99 506 if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
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; 507 return NGX_ERROR;
281 } 508 }
282 509 }
283 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; 510
284 copy->len = name.len; 511 if (sc->conf_prefix || sc->root_prefix) {
285 512 if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
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; 513 return NGX_ERROR;
293 } 514 }
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 } 515 }
301 516
302 if (sc->complete_lengths) { 517 if (sc->complete_lengths) {
303 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);
304 if (code == NULL) { 519 if (code == NULL) {
317 532
318 *code = (uintptr_t) NULL; 533 *code = (uintptr_t) NULL;
319 } 534 }
320 535
321 return NGX_OK; 536 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 } 537 }
396 538
397 539
398 void * 540 void *
399 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) 541 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
431 573
432 return new; 574 return new;
433 } 575 }
434 576
435 577
578 static ngx_int_t
579 ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
580 ngx_uint_t last)
581 {
582 u_char *p;
583 size_t size, len, zero;
584 ngx_http_script_copy_code_t *code;
585
586 zero = (sc->zero && last);
587 len = value->len + zero;
588
589 code = ngx_http_script_add_code(*sc->lengths,
590 sizeof(ngx_http_script_copy_code_t), NULL);
591 if (code == NULL) {
592 return NGX_ERROR;
593 }
594
595 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
596 code->len = len;
597
598 size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
599 & ~(sizeof(uintptr_t) - 1);
600
601 code = ngx_http_script_add_code(*sc->values, size, &sc->main);
602 if (code == NULL) {
603 return NGX_ERROR;
604 }
605
606 code->code = ngx_http_script_copy_code;
607 code->len = len;
608
609 p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
610 value->data, value->len);
611
612 if (zero) {
613 *p = '\0';
614 sc->zero = 0;
615 }
616
617 return NGX_OK;
618 }
619
620
436 size_t 621 size_t
437 ngx_http_script_copy_len_code(ngx_http_script_engine_t *e) 622 ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
438 { 623 {
439 ngx_http_script_copy_code_t *code; 624 ngx_http_script_copy_code_t *code;
440 625
467 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, 652 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
468 "http script copy: \"%*s\"", e->pos - p, p); 653 "http script copy: \"%*s\"", e->pos - p, p);
469 } 654 }
470 655
471 656
657 static ngx_int_t
658 ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name)
659 {
660 ngx_int_t index, *p;
661 ngx_http_script_var_code_t *code;
662
663 index = ngx_http_get_variable_index(sc->cf, name);
664
665 if (index == NGX_ERROR) {
666 return NGX_ERROR;
667 }
668
669 if (sc->flushes) {
670 p = ngx_array_push(*sc->flushes);
671 if (p == NULL) {
672 return NGX_ERROR;
673 }
674
675 *p = index;
676 }
677
678 code = ngx_http_script_add_code(*sc->lengths,
679 sizeof(ngx_http_script_var_code_t), NULL);
680 if (code == NULL) {
681 return NGX_ERROR;
682 }
683
684 code->code = (ngx_http_script_code_pt) ngx_http_script_copy_var_len_code;
685 code->index = (uintptr_t) index;
686
687 code = ngx_http_script_add_code(*sc->values,
688 sizeof(ngx_http_script_var_code_t),
689 &sc->main);
690 if (code == NULL) {
691 return NGX_ERROR;
692 }
693
694 code->code = ngx_http_script_copy_var_code;
695 code->index = (uintptr_t) index;
696
697 return NGX_OK;
698 }
699
700
472 size_t 701 size_t
473 ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e) 702 ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
474 { 703 {
475 ngx_http_variable_value_t *value; 704 ngx_http_variable_value_t *value;
476 ngx_http_script_var_code_t *code; 705 ngx_http_script_var_code_t *code;
521 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, 750 ngx_log_debug2(NGX_LOG_DEBUG_HTTP,
522 e->request->connection->log, 0, 751 e->request->connection->log, 0,
523 "http script var: \"%*s\"", e->pos - p, p); 752 "http script var: \"%*s\"", e->pos - p, p);
524 } 753 }
525 } 754 }
755 }
756
757
758 static ngx_int_t
759 ngx_http_script_add_args_code(ngx_http_script_compile_t *sc)
760 {
761 uintptr_t *code;
762
763 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
764 if (code == NULL) {
765 return NGX_ERROR;
766 }
767
768 *code = (uintptr_t) ngx_http_script_mark_args_code;
769
770 code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main);
771 if (code == NULL) {
772 return NGX_ERROR;
773 }
774
775 *code = (uintptr_t) ngx_http_script_start_args_code;
776
777 return NGX_OK;
526 } 778 }
527 779
528 780
529 size_t 781 size_t
530 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e) 782 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e)
828 return; 1080 return;
829 } 1081 }
830 } 1082 }
831 1083
832 e->ip += sizeof(ngx_http_script_regex_end_code_t); 1084 e->ip += sizeof(ngx_http_script_regex_end_code_t);
1085 }
1086
1087
1088 static ngx_int_t
1089 ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
1090 {
1091 ngx_http_script_copy_capture_code_t *code;
1092
1093 code = ngx_http_script_add_code(*sc->lengths,
1094 sizeof(ngx_http_script_copy_capture_code_t),
1095 NULL);
1096 if (code == NULL) {
1097 return NGX_ERROR;
1098 }
1099
1100 code->code = (ngx_http_script_code_pt)
1101 ngx_http_script_copy_capture_len_code;
1102 code->n = 2 * n;
1103
1104
1105 code = ngx_http_script_add_code(*sc->values,
1106 sizeof(ngx_http_script_copy_capture_code_t),
1107 &sc->main);
1108 if (code == NULL) {
1109 return NGX_ERROR;
1110 }
1111
1112 code->code = ngx_http_script_copy_capture_code;
1113 code->n = 2 * n;
1114
1115 if (sc->ncaptures < n) {
1116 sc->ncaptures = n;
1117 }
1118
1119 return NGX_OK;
833 } 1120 }
834 1121
835 1122
836 size_t 1123 size_t
837 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) 1124 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
911 } 1198 }
912 1199
913 #endif 1200 #endif
914 1201
915 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
916 void 1274 void
917 ngx_http_script_return_code(ngx_http_script_engine_t *e) 1275 ngx_http_script_return_code(ngx_http_script_engine_t *e)
918 { 1276 {
919 ngx_http_script_return_code_t *code; 1277 ngx_http_script_return_code_t *code;
920 1278