blob: ad9d88b4051c575c8b04662955bb5ea8cbae7c69 [file] [log] [blame]
Igor Sysoev7578ec92003-06-02 15:24:30 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoev7578ec92003-06-02 15:24:30 +00007#include <ngx_config.h>
8#include <ngx_core.h>
9#include <ngx_http.h>
10
11
Igor Sysoev165b3c02009-03-18 14:42:06 +000012static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
13static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
14static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
Igor Sysoev8508c102009-03-22 09:36:51 +000015 ngx_str_t *value, ngx_uint_t last);
Igor Sysoev165b3c02009-03-18 14:42:06 +000016static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
17 ngx_str_t *name);
18static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
19#if (NGX_PCRE)
20static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
21 ngx_uint_t n);
22#endif
Igor Sysoev8508c102009-03-22 09:36:51 +000023static ngx_int_t
24 ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
25static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
26static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
Igor Sysoev165b3c02009-03-18 14:42:06 +000027
28
Igor Sysoev899b44e2005-05-12 14:58:06 +000029#define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
30
31static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
32
33
Igor Sysoev8508c102009-03-22 09:36:51 +000034void
Igor Sysoev766f3a92009-03-27 14:59:47 +000035ngx_http_script_flush_complex_value(ngx_http_request_t *r,
Igor Sysoev8508c102009-03-22 09:36:51 +000036 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
56ngx_int_t
57ngx_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
Igor Sysoev766f3a92009-03-27 14:59:47 +000070 ngx_http_script_flush_complex_value(r, val);
Igor Sysoev8508c102009-03-22 09:36:51 +000071
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
106ngx_int_t
107ngx_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
Igor Sysoev8508c102009-03-22 09:36:51 +0000121 nv = 0;
122 nc = 0;
123
124 for (i = 0; i < v->len; i++) {
125 if (v->data[i] == '$') {
126 if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
127 nc++;
128
129 } else {
130 nv++;
131 }
132 }
133 }
134
135 if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) {
136
137 if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
138 return NGX_ERROR;
139 }
140
141 ccv->conf_prefix = 0;
142 ccv->root_prefix = 0;
143 }
144
Igor Sysoev22d381e2009-03-27 06:34:31 +0000145 ccv->complex_value->value = *v;
146 ccv->complex_value->flushes = NULL;
147 ccv->complex_value->lengths = NULL;
148 ccv->complex_value->values = NULL;
149
Igor Sysoev8508c102009-03-22 09:36:51 +0000150 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}
212
213
Igor Sysoev899b44e2005-05-12 14:58:06 +0000214ngx_uint_t
215ngx_http_script_variables_count(ngx_str_t *value)
Igor Sysoev7578ec92003-06-02 15:24:30 +0000216{
Igor Sysoev899b44e2005-05-12 14:58:06 +0000217 ngx_uint_t i, n;
Igor Sysoev02025fd2005-01-18 13:03:58 +0000218
Igor Sysoev899b44e2005-05-12 14:58:06 +0000219 for (n = 0, i = 0; i < value->len; i++) {
220 if (value->data[i] == '$') {
221 n++;
222 }
Igor Sysoev02f742b2005-04-08 15:18:55 +0000223 }
Igor Sysoev02025fd2005-01-18 13:03:58 +0000224
Igor Sysoev899b44e2005-05-12 14:58:06 +0000225 return n;
226}
227
228
229ngx_int_t
230ngx_http_script_compile(ngx_http_script_compile_t *sc)
231{
Igor Sysoev165b3c02009-03-18 14:42:06 +0000232 u_char ch;
233 ngx_str_t name;
234 ngx_uint_t i, bracket;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000235
Igor Sysoev165b3c02009-03-18 14:42:06 +0000236 if (ngx_http_script_init_arrays(sc) != NGX_OK) {
237 return NGX_ERROR;
Igor Sysoev09c684b2005-11-09 17:25:55 +0000238 }
239
Igor Sysoev899b44e2005-05-12 14:58:06 +0000240 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
Igor Sysoev1d05de42009-03-06 12:15:07 +0000250#if (NGX_PCRE)
Igor Sysoev165b3c02009-03-18 14:42:06 +0000251 {
252 ngx_uint_t n;
Igor Sysoev1d05de42009-03-06 12:15:07 +0000253
254 /* NGX_HTTP_MAX_CAPTURES is 9 */
255
Igor Sysoev899b44e2005-05-12 14:58:06 +0000256 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
257
Igor Sysoev7f7846d2006-04-26 09:52:47 +0000258 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
Igor Sysoev165b3c02009-03-18 14:42:06 +0000266 if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000267 return NGX_ERROR;
268 }
269
Igor Sysoev899b44e2005-05-12 14:58:06 +0000270 i++;
271
272 continue;
273 }
Igor Sysoev165b3c02009-03-18 14:42:06 +0000274 }
Igor Sysoev1d05de42009-03-06 12:15:07 +0000275#endif
276
Igor Sysoev899b44e2005-05-12 14:58:06 +0000277 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);
Igor Sysoev02f742b2005-04-08 15:18:55 +0000315 return NGX_ERROR;
316 }
317
Igor Sysoev899b44e2005-05-12 14:58:06 +0000318 if (name.len == 0) {
319 goto invalid_variable;
320 }
Igor Sysoev02f742b2005-04-08 15:18:55 +0000321
Igor Sysoev899b44e2005-05-12 14:58:06 +0000322 sc->variables++;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000323
Igor Sysoev165b3c02009-03-18 14:42:06 +0000324 if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
Igor Sysoev02f742b2005-04-08 15:18:55 +0000325 return NGX_ERROR;
326 }
327
Igor Sysoev02f742b2005-04-08 15:18:55 +0000328 continue;
329 }
330
Igor Sysoev899b44e2005-05-12 14:58:06 +0000331 if (sc->source->data[i] == '?' && sc->compile_args) {
332 sc->args = 1;
333 sc->compile_args = 0;
334
Igor Sysoev165b3c02009-03-18 14:42:06 +0000335 if (ngx_http_script_add_args_code(sc) != NGX_OK) {
Igor Sysoev04610ea2008-02-12 18:05:32 +0000336 return NGX_ERROR;
337 }
338
Igor Sysoev899b44e2005-05-12 14:58:06 +0000339 i++;
340
341 continue;
342 }
343
344 name.data = &sc->source->data[i];
345
Igor Sysoev97860162009-02-10 16:03:42 +0000346 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
Igor Sysoev899b44e2005-05-12 14:58:06 +0000361 i++;
362 name.len++;
363 }
364
365 sc->size += name.len;
366
Igor Sysoev8508c102009-03-22 09:36:51 +0000367 if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
368 != NGX_OK)
369 {
Igor Sysoev02f742b2005-04-08 15:18:55 +0000370 return NGX_ERROR;
371 }
372 }
373
Igor Sysoev165b3c02009-03-18 14:42:06 +0000374 return ngx_http_script_done(sc);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000375
376invalid_variable:
377
378 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
379
380 return NGX_ERROR;
Igor Sysoev7578ec92003-06-02 15:24:30 +0000381}
382
383
Igor Sysoev8fea8852006-03-15 09:53:04 +0000384u_char *
385ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
386 void *code_lengths, size_t len, void *code_values)
387{
Igor Sysoev2c8f0572007-03-30 19:00:34 +0000388 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++) {
Igor Sysoev2d3f3f62007-10-14 18:56:15 +0000397 if (r->variables[i].no_cacheable) {
Igor Sysoev2c8f0572007-03-30 19:00:34 +0000398 r->variables[i].valid = 0;
399 r->variables[i].not_found = 0;
400 }
401 }
Igor Sysoev8fea8852006-03-15 09:53:04 +0000402
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;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000416 value->data = ngx_pnalloc(r->pool, len);
Igor Sysoev8fea8852006-03-15 09:53:04 +0000417 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
Igor Sysoev09c684b2005-11-09 17:25:55 +0000433void
Igor Sysoev2d3f3f62007-10-14 18:56:15 +0000434ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
Igor Sysoev09c684b2005-11-09 17:25:55 +0000435 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++) {
Igor Sysoev2d3f3f62007-10-14 18:56:15 +0000442 if (r->variables[index[n]].no_cacheable) {
Igor Sysoev09c684b2005-11-09 17:25:55 +0000443 r->variables[index[n]].valid = 0;
444 r->variables[index[n]].not_found = 0;
445 }
446 }
447 }
448}
449
450
Igor Sysoev165b3c02009-03-18 14:42:06 +0000451static ngx_int_t
452ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
453{
454 ngx_uint_t n;
455
456 if (sc->flushes && *sc->flushes == NULL) {
457 n = sc->variables ? sc->variables : 1;
458 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
459 if (*sc->flushes == NULL) {
460 return NGX_ERROR;
461 }
462 }
463
464 if (*sc->lengths == NULL) {
465 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
466 + sizeof(ngx_http_script_var_code_t))
467 + sizeof(uintptr_t);
468
469 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
470 if (*sc->lengths == NULL) {
471 return NGX_ERROR;
472 }
473 }
474
475 if (*sc->values == NULL) {
476 n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
477 + sizeof(ngx_http_script_var_code_t))
478 + sizeof(uintptr_t)
479 + sc->source->len
480 + sizeof(uintptr_t) - 1)
481 & ~(sizeof(uintptr_t) - 1);
482
483 *sc->values = ngx_array_create(sc->cf->pool, n, 1);
484 if (*sc->values == NULL) {
485 return NGX_ERROR;
486 }
487 }
488
489 sc->variables = 0;
490
491 return NGX_OK;
492}
493
494
495static ngx_int_t
496ngx_http_script_done(ngx_http_script_compile_t *sc)
497{
Igor Sysoev8508c102009-03-22 09:36:51 +0000498 ngx_str_t zero;
Igor Sysoev165b3c02009-03-18 14:42:06 +0000499 uintptr_t *code;
500
Igor Sysoev8508c102009-03-22 09:36:51 +0000501 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 }
516
Igor Sysoev165b3c02009-03-18 14:42:06 +0000517 if (sc->complete_lengths) {
518 code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
519 if (code == NULL) {
520 return NGX_ERROR;
521 }
522
523 *code = (uintptr_t) NULL;
524 }
525
526 if (sc->complete_values) {
527 code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
528 &sc->main);
529 if (code == NULL) {
530 return NGX_ERROR;
531 }
532
533 *code = (uintptr_t) NULL;
534 }
535
536 return NGX_OK;
537}
538
539
Igor Sysoev899b44e2005-05-12 14:58:06 +0000540void *
Igor Sysoev02f742b2005-04-08 15:18:55 +0000541ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
Igor Sysoev7578ec92003-06-02 15:24:30 +0000542{
Igor Sysoev02f742b2005-04-08 15:18:55 +0000543 if (*codes == NULL) {
544 *codes = ngx_array_create(pool, 256, 1);
545 if (*codes == NULL) {
546 return NULL;
547 }
548 }
Igor Sysoev7578ec92003-06-02 15:24:30 +0000549
Igor Sysoev02f742b2005-04-08 15:18:55 +0000550 return ngx_array_push_n(*codes, size);
551}
Igor Sysoev7578ec92003-06-02 15:24:30 +0000552
Igor Sysoev899b44e2005-05-12 14:58:06 +0000553
554void *
555ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
556{
557 u_char *elts, **p;
558 void *new;
559
560 elts = codes->elts;
561
562 new = ngx_array_push_n(codes, size);
563 if (new == NULL) {
Igor Sysoev05822df2009-06-02 16:08:38 +0000564 return NULL;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000565 }
566
567 if (code) {
568 if (elts != codes->elts) {
569 p = code;
570 *p += (u_char *) codes->elts - elts;
571 }
572 }
573
574 return new;
575}
Igor Sysoev02025fd2005-01-18 13:03:58 +0000576
Igor Sysoev02f742b2005-04-08 15:18:55 +0000577
Igor Sysoev165b3c02009-03-18 14:42:06 +0000578static ngx_int_t
Igor Sysoev8508c102009-03-22 09:36:51 +0000579ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
580 ngx_uint_t last)
Igor Sysoev165b3c02009-03-18 14:42:06 +0000581{
Igor Sysoev8508c102009-03-22 09:36:51 +0000582 u_char *p;
583 size_t size, len, zero;
Igor Sysoev165b3c02009-03-18 14:42:06 +0000584 ngx_http_script_copy_code_t *code;
585
Igor Sysoev8508c102009-03-22 09:36:51 +0000586 zero = (sc->zero && last);
587 len = value->len + zero;
588
Igor Sysoev165b3c02009-03-18 14:42:06 +0000589 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;
Igor Sysoev8508c102009-03-22 09:36:51 +0000596 code->len = len;
Igor Sysoev165b3c02009-03-18 14:42:06 +0000597
Igor Sysoev8508c102009-03-22 09:36:51 +0000598 size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
Igor Sysoev165b3c02009-03-18 14:42:06 +0000599 & ~(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;
Igor Sysoev8508c102009-03-22 09:36:51 +0000607 code->len = len;
Igor Sysoev165b3c02009-03-18 14:42:06 +0000608
Igor Sysoev8508c102009-03-22 09:36:51 +0000609 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 }
Igor Sysoev165b3c02009-03-18 14:42:06 +0000616
617 return NGX_OK;
618}
619
620
Igor Sysoev02f742b2005-04-08 15:18:55 +0000621size_t
Igor Sysoev899b44e2005-05-12 14:58:06 +0000622ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
Igor Sysoev02f742b2005-04-08 15:18:55 +0000623{
624 ngx_http_script_copy_code_t *code;
625
Igor Sysoev899b44e2005-05-12 14:58:06 +0000626 code = (ngx_http_script_copy_code_t *) e->ip;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000627
Igor Sysoev899b44e2005-05-12 14:58:06 +0000628 e->ip += sizeof(ngx_http_script_copy_code_t);
Igor Sysoev02f742b2005-04-08 15:18:55 +0000629
630 return code->len;
Igor Sysoev7578ec92003-06-02 15:24:30 +0000631}
632
633
Igor Sysoev02f742b2005-04-08 15:18:55 +0000634void
Igor Sysoev899b44e2005-05-12 14:58:06 +0000635ngx_http_script_copy_code(ngx_http_script_engine_t *e)
Igor Sysoev7578ec92003-06-02 15:24:30 +0000636{
Igor Sysoev45656b42008-12-10 14:48:04 +0000637 u_char *p;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000638 ngx_http_script_copy_code_t *code;
639
Igor Sysoev899b44e2005-05-12 14:58:06 +0000640 code = (ngx_http_script_copy_code_t *) e->ip;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000641
Igor Sysoev45656b42008-12-10 14:48:04 +0000642 p = e->pos;
643
Igor Sysoev899b44e2005-05-12 14:58:06 +0000644 if (!e->skip) {
Igor Sysoev45656b42008-12-10 14:48:04 +0000645 e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_script_copy_code_t),
Igor Sysoev09c684b2005-11-09 17:25:55 +0000646 code->len);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000647 }
Igor Sysoev02f742b2005-04-08 15:18:55 +0000648
Igor Sysoev899b44e2005-05-12 14:58:06 +0000649 e->ip += sizeof(ngx_http_script_copy_code_t)
650 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
651
Igor Sysoev45656b42008-12-10 14:48:04 +0000652 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
653 "http script copy: \"%*s\"", e->pos - p, p);
Igor Sysoev7578ec92003-06-02 15:24:30 +0000654}
655
656
Igor Sysoev165b3c02009-03-18 14:42:06 +0000657static ngx_int_t
658ngx_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
Igor Sysoev02f742b2005-04-08 15:18:55 +0000701size_t
Igor Sysoev899b44e2005-05-12 14:58:06 +0000702ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
Igor Sysoev7578ec92003-06-02 15:24:30 +0000703{
Igor Sysoev02f742b2005-04-08 15:18:55 +0000704 ngx_http_variable_value_t *value;
705 ngx_http_script_var_code_t *code;
706
Igor Sysoev899b44e2005-05-12 14:58:06 +0000707 code = (ngx_http_script_var_code_t *) e->ip;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000708
Igor Sysoev899b44e2005-05-12 14:58:06 +0000709 e->ip += sizeof(ngx_http_script_var_code_t);
Igor Sysoev02f742b2005-04-08 15:18:55 +0000710
Igor Sysoev09c684b2005-11-09 17:25:55 +0000711 if (e->flushed) {
712 value = ngx_http_get_indexed_variable(e->request, code->index);
Igor Sysoev02f742b2005-04-08 15:18:55 +0000713
Igor Sysoev09c684b2005-11-09 17:25:55 +0000714 } else {
715 value = ngx_http_get_flushed_variable(e->request, code->index);
716 }
717
718 if (value && !value->not_found) {
719 return value->len;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000720 }
721
Igor Sysoevf6e1fe32005-10-04 10:38:53 +0000722 return 0;
Igor Sysoev7578ec92003-06-02 15:24:30 +0000723}
724
725
Igor Sysoev02f742b2005-04-08 15:18:55 +0000726void
Igor Sysoev899b44e2005-05-12 14:58:06 +0000727ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
Igor Sysoev7578ec92003-06-02 15:24:30 +0000728{
Igor Sysoev45656b42008-12-10 14:48:04 +0000729 u_char *p;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000730 ngx_http_variable_value_t *value;
731 ngx_http_script_var_code_t *code;
732
Igor Sysoev899b44e2005-05-12 14:58:06 +0000733 code = (ngx_http_script_var_code_t *) e->ip;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000734
Igor Sysoev899b44e2005-05-12 14:58:06 +0000735 e->ip += sizeof(ngx_http_script_var_code_t);
Igor Sysoev02f742b2005-04-08 15:18:55 +0000736
Igor Sysoev899b44e2005-05-12 14:58:06 +0000737 if (!e->skip) {
Igor Sysoev02f742b2005-04-08 15:18:55 +0000738
Igor Sysoev09c684b2005-11-09 17:25:55 +0000739 if (e->flushed) {
740 value = ngx_http_get_indexed_variable(e->request, code->index);
741
742 } else {
743 value = ngx_http_get_flushed_variable(e->request, code->index);
744 }
745
746 if (value && !value->not_found) {
Igor Sysoev45656b42008-12-10 14:48:04 +0000747 p = e->pos;
748 e->pos = ngx_copy(p, value->data, value->len);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000749
Igor Sysoev45656b42008-12-10 14:48:04 +0000750 ngx_log_debug2(NGX_LOG_DEBUG_HTTP,
Igor Sysoev58364232006-11-14 12:45:03 +0000751 e->request->connection->log, 0,
Igor Sysoev45656b42008-12-10 14:48:04 +0000752 "http script var: \"%*s\"", e->pos - p, p);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000753 }
754 }
755}
756
757
Igor Sysoev165b3c02009-03-18 14:42:06 +0000758static ngx_int_t
759ngx_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;
778}
779
780
Igor Sysoev899b44e2005-05-12 14:58:06 +0000781size_t
Igor Sysoev04610ea2008-02-12 18:05:32 +0000782ngx_http_script_mark_args_code(ngx_http_script_engine_t *e)
783{
784 e->is_args = 1;
785 e->ip += sizeof(uintptr_t);
786
787 return 1;
788}
789
790
Igor Sysoev899b44e2005-05-12 14:58:06 +0000791void
792ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
793{
794 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
795 "http script args");
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +0000796
Igor Sysoev4084b122008-09-01 14:43:38 +0000797 e->is_args = 1;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000798 e->args = e->pos;
799 e->ip += sizeof(uintptr_t);
800}
801
802
Igor Sysoev4959ec42005-05-23 12:07:45 +0000803#if (NGX_PCRE)
804
Igor Sysoev899b44e2005-05-12 14:58:06 +0000805void
806ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
807{
808 size_t len;
809 ngx_int_t rc;
810 ngx_uint_t n;
811 ngx_http_request_t *r;
812 ngx_http_script_engine_t le;
813 ngx_http_script_len_code_pt lcode;
814 ngx_http_script_regex_code_t *code;
815
816 code = (ngx_http_script_regex_code_t *) e->ip;
817
818 r = e->request;
819
820 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
821 "http script regex: \"%V\"", &code->name);
822
823 if (code->uri) {
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000824 e->line = r->uri;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000825 } else {
826 e->sp--;
Igor Sysoev09c684b2005-11-09 17:25:55 +0000827 e->line.len = e->sp->len;
828 e->line.data = e->sp->data;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000829 }
830
Igor Sysoev1d05de42009-03-06 12:15:07 +0000831 if (code->ncaptures && r->captures == NULL) {
832
833 r->captures = ngx_palloc(r->pool,
834 (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int));
835 if (r->captures == NULL) {
836 e->ip = ngx_http_script_exit;
837 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
838 return;
839 }
840 }
841
842 rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000843
844 if (rc == NGX_REGEX_NO_MATCHED) {
Igor Sysoev0e179532008-12-11 06:38:14 +0000845 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000846 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000847 "\"%V\" does not match \"%V\"",
848 &code->name, &e->line);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000849 }
850
Igor Sysoev1d05de42009-03-06 12:15:07 +0000851 r->ncaptures = 0;
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000852
Igor Sysoev899b44e2005-05-12 14:58:06 +0000853 if (code->test) {
Igor Sysoev94e32ce2006-04-07 14:08:04 +0000854 if (code->negative_test) {
855 e->sp->len = 1;
856 e->sp->data = (u_char *) "1";
857
858 } else {
859 e->sp->len = 0;
860 e->sp->data = (u_char *) "";
861 }
862
Igor Sysoev899b44e2005-05-12 14:58:06 +0000863 e->sp++;
864
865 e->ip += sizeof(ngx_http_script_regex_code_t);
866 return;
867 }
868
869 e->ip += code->next;
Igor Sysoev02f742b2005-04-08 15:18:55 +0000870 return;
871 }
872
Igor Sysoev899b44e2005-05-12 14:58:06 +0000873 if (rc < 0) {
874 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
875 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000876 rc, &e->line, &code->name);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000877
878 e->ip = ngx_http_script_exit;
879 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
880 return;
881 }
882
Igor Sysoev0e179532008-12-11 06:38:14 +0000883 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000884 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000885 "\"%V\" matches \"%V\"", &code->name, &e->line);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000886 }
887
Igor Sysoev1d05de42009-03-06 12:15:07 +0000888 r->ncaptures = code->ncaptures;
889 r->captures_data = e->line.data;
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000890
Igor Sysoev899b44e2005-05-12 14:58:06 +0000891 if (code->test) {
Igor Sysoev94e32ce2006-04-07 14:08:04 +0000892 if (code->negative_test) {
893 e->sp->len = 0;
894 e->sp->data = (u_char *) "";
895
896 } else {
897 e->sp->len = 1;
898 e->sp->data = (u_char *) "1";
899 }
900
Igor Sysoev899b44e2005-05-12 14:58:06 +0000901 e->sp++;
902
903 e->ip += sizeof(ngx_http_script_regex_code_t);
904 return;
905 }
906
907 if (code->status) {
908 e->status = code->status;
909
910 if (!code->redirect) {
911 e->ip = ngx_http_script_exit;
912 return;
913 }
914 }
915
916 if (code->uri) {
917 r->internal = 1;
918 r->valid_unparsed_uri = 0;
919
920 if (code->break_cycle) {
921 r->valid_location = 0;
Igor Sysoev5192b362005-07-08 14:34:20 +0000922 r->uri_changed = 0;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000923
924 } else {
925 r->uri_changed = 1;
926 }
927 }
928
929 if (code->lengths == NULL) {
930 e->buf.len = code->size;
931
932 if (code->uri) {
933 if (rc && (r->quoted_uri || r->plus_in_uri)) {
934 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
935 NGX_ESCAPE_ARGS);
936 }
937 }
938
939 for (n = 1; n < (ngx_uint_t) rc; n++) {
Igor Sysoev1d05de42009-03-06 12:15:07 +0000940 e->buf.len += r->captures[2 * n + 1] - r->captures[2 * n];
Igor Sysoev899b44e2005-05-12 14:58:06 +0000941 }
942
943 } else {
944 ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
945
946 le.ip = code->lengths->elts;
Igor Sysoev3f8dc592006-08-28 16:57:48 +0000947 le.line = e->line;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000948 le.request = r;
Igor Sysoev3f8dc592006-08-28 16:57:48 +0000949 le.quote = code->redirect;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000950
Igor Sysoev04610ea2008-02-12 18:05:32 +0000951 len = 0;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000952
953 while (*(uintptr_t *) le.ip) {
954 lcode = *(ngx_http_script_len_code_pt *) le.ip;
955 len += lcode(&le);
956 }
957
958 e->buf.len = len;
Igor Sysoev04610ea2008-02-12 18:05:32 +0000959 e->is_args = le.is_args;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000960 }
961
Igor Sysoeve31e90b2005-05-19 13:25:22 +0000962 if (code->add_args && r->args.len) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000963 e->buf.len += r->args.len + 1;
964 }
965
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000966 e->buf.data = ngx_pnalloc(r->pool, e->buf.len);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000967 if (e->buf.data == NULL) {
968 e->ip = ngx_http_script_exit;
969 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
970 return;
971 }
972
973 e->quote = code->redirect;
974
975 e->pos = e->buf.data;
976
977 e->ip += sizeof(ngx_http_script_regex_code_t);
978}
979
980
981void
982ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
983{
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +0000984 u_char *dst, *src;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000985 ngx_http_request_t *r;
986 ngx_http_script_regex_end_code_t *code;
987
988 code = (ngx_http_script_regex_end_code_t *) e->ip;
989
990 r = e->request;
991
992 e->quote = 0;
993
994 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
995 "http script regex end");
996
997 if (code->redirect) {
998
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +0000999 dst = e->buf.data;
1000 src = e->buf.data;
1001
Igor Sysoevf0a51cf2007-10-22 10:19:17 +00001002 ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
1003 NGX_UNESCAPE_REDIRECT);
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001004
1005 if (src < e->pos) {
1006 dst = ngx_copy(dst, src, e->pos - src);
1007 }
1008
1009 e->pos = dst;
1010
1011 if (code->add_args && r->args.len) {
Igor Sysoev899b44e2005-05-12 14:58:06 +00001012 *e->pos++ = (u_char) (code->args ? '&' : '?');
Igor Sysoev09c684b2005-11-09 17:25:55 +00001013 e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001014 }
1015
1016 e->buf.len = e->pos - e->buf.data;
1017
Igor Sysoev0e179532008-12-11 06:38:14 +00001018 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
Igor Sysoev899b44e2005-05-12 14:58:06 +00001019 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
1020 "rewritten redirect: \"%V\"", &e->buf);
1021 }
1022
1023 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
1024 if (r->headers_out.location == NULL) {
1025 e->ip = ngx_http_script_exit;
1026 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1027 return;
1028 }
1029
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001030 r->headers_out.location->hash = 1;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001031 r->headers_out.location->key.len = sizeof("Location") - 1;
1032 r->headers_out.location->key.data = (u_char *) "Location";
1033 r->headers_out.location->value = e->buf;
1034
1035 e->ip += sizeof(ngx_http_script_regex_end_code_t);
1036 return;
1037 }
1038
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001039 if (e->args) {
Igor Sysoev899b44e2005-05-12 14:58:06 +00001040 e->buf.len = e->args - e->buf.data;
1041
1042 if (code->add_args && r->args.len) {
1043 *e->pos++ = '&';
Igor Sysoev09c684b2005-11-09 17:25:55 +00001044 e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001045 }
1046
1047 r->args.len = e->pos - e->args;
1048 r->args.data = e->args;
1049
1050 e->args = NULL;
1051
1052 } else {
1053 e->buf.len = e->pos - e->buf.data;
Igor Sysoev08e63d42006-08-14 15:09:38 +00001054
1055 if (!code->add_args) {
1056 r->args.len = 0;
1057 }
Igor Sysoev899b44e2005-05-12 14:58:06 +00001058 }
1059
Igor Sysoev0e179532008-12-11 06:38:14 +00001060 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
Igor Sysoev899b44e2005-05-12 14:58:06 +00001061 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
1062 "rewritten data: \"%V\", args: \"%V\"",
1063 &e->buf, &r->args);
1064 }
1065
1066 if (code->uri) {
1067 r->uri = e->buf;
1068
Igor Sysoevb85fd592005-08-23 15:36:54 +00001069 if (r->uri.len == 0) {
1070 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1071 "the rewritten URI has a zero length");
1072 e->ip = ngx_http_script_exit;
1073 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1074 return;
1075 }
1076
Igor Sysoevc28d6322009-07-14 08:38:28 +00001077 ngx_http_set_exten(r);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001078 }
1079
1080 e->ip += sizeof(ngx_http_script_regex_end_code_t);
1081}
1082
Igor Sysoev1d05de42009-03-06 12:15:07 +00001083
Igor Sysoev165b3c02009-03-18 14:42:06 +00001084static ngx_int_t
1085ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
1086{
1087 ngx_http_script_copy_capture_code_t *code;
1088
1089 code = ngx_http_script_add_code(*sc->lengths,
1090 sizeof(ngx_http_script_copy_capture_code_t),
1091 NULL);
1092 if (code == NULL) {
1093 return NGX_ERROR;
1094 }
1095
1096 code->code = (ngx_http_script_code_pt)
1097 ngx_http_script_copy_capture_len_code;
1098 code->n = 2 * n;
1099
1100
1101 code = ngx_http_script_add_code(*sc->values,
1102 sizeof(ngx_http_script_copy_capture_code_t),
1103 &sc->main);
1104 if (code == NULL) {
1105 return NGX_ERROR;
1106 }
1107
1108 code->code = ngx_http_script_copy_capture_code;
1109 code->n = 2 * n;
1110
1111 if (sc->ncaptures < n) {
1112 sc->ncaptures = n;
1113 }
1114
1115 return NGX_OK;
1116}
1117
1118
Igor Sysoev1d05de42009-03-06 12:15:07 +00001119size_t
1120ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
1121{
1122 int *cap;
1123 u_char *p;
1124 ngx_uint_t n;
1125 ngx_http_request_t *r;
1126 ngx_http_script_copy_capture_code_t *code;
1127
1128 r = e->request;
1129
1130 code = (ngx_http_script_copy_capture_code_t *) e->ip;
1131
1132 e->ip += sizeof(ngx_http_script_copy_capture_code_t);
1133
1134 n = code->n;
1135
1136 if (n < r->ncaptures) {
1137
1138 cap = r->captures;
1139
1140 if ((e->is_args || e->quote)
1141 && (e->request->quoted_uri || e->request->plus_in_uri))
1142 {
1143 p = r->captures_data;
1144
1145 return cap[n + 1] - cap[n]
1146 + 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n],
1147 NGX_ESCAPE_ARGS);
1148 } else {
1149 return cap[n + 1] - cap[n];
1150 }
1151 }
1152
1153 return 0;
1154}
1155
1156
1157void
1158ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
1159{
1160 int *cap;
1161 u_char *p, *pos;
1162 ngx_uint_t n;
1163 ngx_http_request_t *r;
1164 ngx_http_script_copy_capture_code_t *code;
1165
1166 r = e->request;
1167
1168 code = (ngx_http_script_copy_capture_code_t *) e->ip;
1169
1170 e->ip += sizeof(ngx_http_script_copy_capture_code_t);
1171
1172 n = code->n;
1173
1174 pos = e->pos;
1175
1176 if (n < r->ncaptures) {
1177
1178 cap = r->captures;
1179 p = r->captures_data;
1180
1181 if ((e->is_args || e->quote)
1182 && (e->request->quoted_uri || e->request->plus_in_uri))
1183 {
1184 e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
1185 cap[n + 1] - cap[n],
1186 NGX_ESCAPE_ARGS);
1187 } else {
1188 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
1189 }
1190 }
1191
1192 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1193 "http script capture: \"%*s\"", e->pos - pos, pos);
1194}
1195
Igor Sysoev4959ec42005-05-23 12:07:45 +00001196#endif
1197
Igor Sysoev899b44e2005-05-12 14:58:06 +00001198
Igor Sysoev8508c102009-03-22 09:36:51 +00001199static ngx_int_t
1200ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
1201{
1202 ngx_http_script_full_name_code_t *code;
1203
1204 code = ngx_http_script_add_code(*sc->lengths,
1205 sizeof(ngx_http_script_full_name_code_t),
1206 NULL);
1207 if (code == NULL) {
1208 return NGX_ERROR;
1209 }
1210
1211 code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
Igor Sysoev5ef370d2009-04-27 11:32:33 +00001212 code->conf_prefix = sc->conf_prefix;
Igor Sysoev8508c102009-03-22 09:36:51 +00001213
1214 code = ngx_http_script_add_code(*sc->values,
1215 sizeof(ngx_http_script_full_name_code_t),
1216 &sc->main);
1217 if (code == NULL) {
1218 return NGX_ERROR;
1219 }
1220
1221 code->code = ngx_http_script_full_name_code;
Igor Sysoev5ef370d2009-04-27 11:32:33 +00001222 code->conf_prefix = sc->conf_prefix;
Igor Sysoev8508c102009-03-22 09:36:51 +00001223
1224 return NGX_OK;
1225}
1226
1227
1228static size_t
1229ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
1230{
1231 ngx_http_script_full_name_code_t *code;
1232
1233 code = (ngx_http_script_full_name_code_t *) e->ip;
1234
1235 e->ip += sizeof(ngx_http_script_full_name_code_t);
1236
Igor Sysoev5ef370d2009-04-27 11:32:33 +00001237 return code->conf_prefix ? ngx_cycle->conf_prefix.len:
1238 ngx_cycle->prefix.len;
Igor Sysoev8508c102009-03-22 09:36:51 +00001239}
1240
1241
1242static void
1243ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
1244{
1245 ngx_http_script_full_name_code_t *code;
1246
1247 ngx_str_t value;
1248
1249 code = (ngx_http_script_full_name_code_t *) e->ip;
1250
1251 value.data = e->buf.data;
1252 value.len = e->pos - e->buf.data;
1253
Igor Sysoev5ef370d2009-04-27 11:32:33 +00001254 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
Igor Sysoev8508c102009-03-22 09:36:51 +00001255 != NGX_OK)
1256 {
1257 e->ip = ngx_http_script_exit;
1258 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1259 return;
1260 }
1261
1262 e->buf = value;
1263
1264 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1265 "http script fullname: \"%V\"", &value);
1266
1267 e->ip += sizeof(ngx_http_script_full_name_code_t);
1268}
1269
1270
Igor Sysoev899b44e2005-05-12 14:58:06 +00001271void
1272ngx_http_script_return_code(ngx_http_script_engine_t *e)
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001273{
Igor Sysoev899b44e2005-05-12 14:58:06 +00001274 ngx_http_script_return_code_t *code;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001275
Igor Sysoev899b44e2005-05-12 14:58:06 +00001276 code = (ngx_http_script_return_code_t *) e->ip;
1277
1278 e->status = code->status;
1279
Igor Sysoevafd7ec52006-05-29 17:28:12 +00001280 if (code->status == NGX_HTTP_NO_CONTENT) {
1281 e->request->header_only = 1;
Igor Sysoev8fd830a2006-10-02 10:22:51 +00001282 e->request->zero_body = 1;
Igor Sysoevafd7ec52006-05-29 17:28:12 +00001283 }
1284
Igor Sysoev899b44e2005-05-12 14:58:06 +00001285 e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t);
1286}
1287
1288
1289void
Igor Sysoev5192b362005-07-08 14:34:20 +00001290ngx_http_script_break_code(ngx_http_script_engine_t *e)
1291{
1292 e->request->uri_changed = 0;
1293
1294 e->ip = ngx_http_script_exit;
1295}
1296
1297
1298void
Igor Sysoev899b44e2005-05-12 14:58:06 +00001299ngx_http_script_if_code(ngx_http_script_engine_t *e)
1300{
1301 ngx_http_script_if_code_t *code;
1302
1303 code = (ngx_http_script_if_code_t *) e->ip;
1304
1305 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1306 "http script if");
1307
1308 e->sp--;
1309
Igor Sysoev09c684b2005-11-09 17:25:55 +00001310 if (e->sp->len && e->sp->data[0] != '0') {
Igor Sysoev899b44e2005-05-12 14:58:06 +00001311 if (code->loc_conf) {
1312 e->request->loc_conf = code->loc_conf;
Igor Sysoevb85fd592005-08-23 15:36:54 +00001313 ngx_http_update_location_config(e->request);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001314 }
1315
1316 e->ip += sizeof(ngx_http_script_if_code_t);
1317 return;
1318 }
1319
1320 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001321 "http script if: false");
Igor Sysoev899b44e2005-05-12 14:58:06 +00001322
1323 e->ip += code->next;
1324}
1325
1326
1327void
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001328ngx_http_script_equal_code(ngx_http_script_engine_t *e)
1329{
1330 ngx_http_variable_value_t *val, *res;
1331
1332 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1333 "http script equal");
1334
1335 e->sp--;
1336 val = e->sp;
1337 res = e->sp - 1;
1338
1339 e->ip += sizeof(uintptr_t);
1340
Igor Sysoev45656b42008-12-10 14:48:04 +00001341 if (val->len == res->len
1342 && ngx_strncmp(val->data, res->data, res->len) == 0)
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001343 {
1344 *res = ngx_http_variable_true_value;
1345 return;
1346 }
1347
1348 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1349 "http script equal: no");
1350
1351 *res = ngx_http_variable_null_value;
1352}
1353
1354
1355void
1356ngx_http_script_not_equal_code(ngx_http_script_engine_t *e)
1357{
1358 ngx_http_variable_value_t *val, *res;
1359
1360 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1361 "http script not equal");
1362
1363 e->sp--;
1364 val = e->sp;
1365 res = e->sp - 1;
1366
1367 e->ip += sizeof(uintptr_t);
1368
Igor Sysoev45656b42008-12-10 14:48:04 +00001369 if (val->len == res->len
1370 && ngx_strncmp(val->data, res->data, res->len) == 0)
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001371 {
1372 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1373 "http script not equal: no");
1374
1375 *res = ngx_http_variable_null_value;
1376 return;
1377 }
1378
1379 *res = ngx_http_variable_true_value;
1380}
1381
1382
1383void
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001384ngx_http_script_file_code(ngx_http_script_engine_t *e)
1385{
Igor Sysoev140c7552007-09-01 12:12:48 +00001386 ngx_str_t path;
1387 ngx_http_request_t *r;
1388 ngx_open_file_info_t of;
1389 ngx_http_core_loc_conf_t *clcf;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001390 ngx_http_variable_value_t *value;
1391 ngx_http_script_file_code_t *code;
1392
1393 value = e->sp - 1;
1394
1395 code = (ngx_http_script_file_code_t *) e->ip;
1396 e->ip += sizeof(ngx_http_script_file_code_t);
1397
Igor Sysoev140c7552007-09-01 12:12:48 +00001398 path.len = value->len - 1;
1399 path.data = value->data;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001400
Igor Sysoev140c7552007-09-01 12:12:48 +00001401 r = e->request;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001402
Igor Sysoev140c7552007-09-01 12:12:48 +00001403 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1404 "http script file op %p \"%V\"", code->op, &path);
1405
1406 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1407
Igor Sysoev5a0eac82008-06-26 14:07:59 +00001408 ngx_memzero(&of, sizeof(ngx_open_file_info_t));
1409
Igor Sysoev385af282008-07-30 12:34:04 +00001410 of.directio = clcf->directio;
Igor Sysoev9b9616e2007-12-21 16:19:48 +00001411 of.valid = clcf->open_file_cache_valid;
Igor Sysoevf3b0e492007-12-22 13:19:39 +00001412 of.min_uses = clcf->open_file_cache_min_uses;
Igor Sysoevf1cc4572009-04-27 09:55:53 +00001413 of.test_only = 1;
Igor Sysoev140c7552007-09-01 12:12:48 +00001414 of.errors = clcf->open_file_cache_errors;
Igor Sysoev9afd58f2007-09-03 08:41:42 +00001415 of.events = clcf->open_file_cache_events;
Igor Sysoev140c7552007-09-01 12:12:48 +00001416
1417 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
Igor Sysoev86b91592007-12-27 20:32:43 +00001418 != NGX_OK)
Igor Sysoev140c7552007-09-01 12:12:48 +00001419 {
1420 if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
1421 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
Igor Sysoevf1cc4572009-04-27 09:55:53 +00001422 "%s \"%s\" failed", of.failed, value->data);
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001423 }
1424
1425 switch (code->op) {
Igor Sysoevc55a1042006-08-09 19:59:45 +00001426
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001427 case ngx_http_script_file_plain:
Igor Sysoevb71c6902006-08-04 16:04:04 +00001428 case ngx_http_script_file_dir:
1429 case ngx_http_script_file_exists:
1430 case ngx_http_script_file_exec:
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001431 goto false_value;
Igor Sysoevc55a1042006-08-09 19:59:45 +00001432
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001433 case ngx_http_script_file_not_plain:
Igor Sysoevb71c6902006-08-04 16:04:04 +00001434 case ngx_http_script_file_not_dir:
Igor Sysoevc55a1042006-08-09 19:59:45 +00001435 case ngx_http_script_file_not_exists:
Igor Sysoevb71c6902006-08-04 16:04:04 +00001436 case ngx_http_script_file_not_exec:
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001437 goto true_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001438 }
1439
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001440 goto false_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001441 }
1442
1443 switch (code->op) {
1444 case ngx_http_script_file_plain:
Igor Sysoev140c7552007-09-01 12:12:48 +00001445 if (of.is_file) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001446 goto true_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001447 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001448 goto false_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001449
1450 case ngx_http_script_file_not_plain:
Igor Sysoev140c7552007-09-01 12:12:48 +00001451 if (of.is_file) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001452 goto false_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001453 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001454 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001455
1456 case ngx_http_script_file_dir:
Igor Sysoev140c7552007-09-01 12:12:48 +00001457 if (of.is_dir) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001458 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001459 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001460 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001461
1462 case ngx_http_script_file_not_dir:
Igor Sysoev140c7552007-09-01 12:12:48 +00001463 if (of.is_dir) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001464 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001465 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001466 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001467
1468 case ngx_http_script_file_exists:
Igor Sysoev140c7552007-09-01 12:12:48 +00001469 if (of.is_file || of.is_dir || of.is_link) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001470 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001471 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001472 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001473
1474 case ngx_http_script_file_not_exists:
Igor Sysoev140c7552007-09-01 12:12:48 +00001475 if (of.is_file || of.is_dir || of.is_link) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001476 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001477 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001478 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001479
Igor Sysoevb71c6902006-08-04 16:04:04 +00001480 case ngx_http_script_file_exec:
Igor Sysoev140c7552007-09-01 12:12:48 +00001481 if (of.is_exec) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001482 goto true_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001483 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001484 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001485
1486 case ngx_http_script_file_not_exec:
Igor Sysoev140c7552007-09-01 12:12:48 +00001487 if (of.is_exec) {
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001488 goto false_value;
Igor Sysoevb71c6902006-08-04 16:04:04 +00001489 }
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001490 goto true_value;
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001491 }
1492
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001493false_value:
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001494
Igor Sysoev140c7552007-09-01 12:12:48 +00001495 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001496 "http script file op false");
1497
1498 *value = ngx_http_variable_null_value;
1499 return;
1500
Igor Sysoeva3e9f7d2008-07-31 07:55:46 +00001501true_value:
Igor Sysoev94e32ce2006-04-07 14:08:04 +00001502
1503 *value = ngx_http_variable_true_value;
1504 return;
1505}
1506
1507
1508void
Igor Sysoeve31e90b2005-05-19 13:25:22 +00001509ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
1510{
1511 size_t len;
1512 ngx_http_script_engine_t le;
1513 ngx_http_script_len_code_pt lcode;
1514 ngx_http_script_complex_value_code_t *code;
1515
1516 code = (ngx_http_script_complex_value_code_t *) e->ip;
1517
1518 e->ip += sizeof(ngx_http_script_complex_value_code_t);
1519
1520 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1521 "http script complex value");
1522
1523 ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
1524
1525 le.ip = code->lengths->elts;
Igor Sysoevaf3b7ea2006-05-31 14:11:45 +00001526 le.line = e->line;
Igor Sysoeve31e90b2005-05-19 13:25:22 +00001527 le.request = e->request;
Igor Sysoevaf3b7ea2006-05-31 14:11:45 +00001528 le.quote = e->quote;
Igor Sysoeve31e90b2005-05-19 13:25:22 +00001529
1530 for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
1531 lcode = *(ngx_http_script_len_code_pt *) le.ip;
1532 }
1533
1534 e->buf.len = len;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +00001535 e->buf.data = ngx_pnalloc(e->request->pool, len);
Igor Sysoeve31e90b2005-05-19 13:25:22 +00001536 if (e->buf.data == NULL) {
1537 e->ip = ngx_http_script_exit;
1538 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1539 return;
1540 }
1541
1542 e->pos = e->buf.data;
1543
Igor Sysoev09c684b2005-11-09 17:25:55 +00001544 e->sp->len = e->buf.len;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001545 e->sp->data = e->buf.data;
Igor Sysoeve31e90b2005-05-19 13:25:22 +00001546 e->sp++;
1547}
1548
1549
1550void
Igor Sysoev899b44e2005-05-12 14:58:06 +00001551ngx_http_script_value_code(ngx_http_script_engine_t *e)
1552{
1553 ngx_http_script_value_code_t *code;
1554
1555 code = (ngx_http_script_value_code_t *) e->ip;
1556
1557 e->ip += sizeof(ngx_http_script_value_code_t);
1558
Igor Sysoev09c684b2005-11-09 17:25:55 +00001559 e->sp->len = code->text_len;
1560 e->sp->data = (u_char *) code->text_data;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001561
1562 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
Igor Sysoev5ba67392007-10-09 18:44:59 +00001563 "http script value: \"%v\"", e->sp);
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001564
Igor Sysoev899b44e2005-05-12 14:58:06 +00001565 e->sp++;
1566}
1567
1568
1569void
1570ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
1571{
1572 ngx_http_request_t *r;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001573 ngx_http_script_var_code_t *code;
1574
Igor Sysoev899b44e2005-05-12 14:58:06 +00001575 code = (ngx_http_script_var_code_t *) e->ip;
1576
1577 e->ip += sizeof(ngx_http_script_var_code_t);
1578
1579 r = e->request;
1580
Igor Sysoev899b44e2005-05-12 14:58:06 +00001581 e->sp--;
1582
Igor Sysoev09c684b2005-11-09 17:25:55 +00001583 r->variables[code->index].len = e->sp->len;
1584 r->variables[code->index].valid = 1;
Igor Sysoev2d3f3f62007-10-14 18:56:15 +00001585 r->variables[code->index].no_cacheable = 0;
Igor Sysoev09c684b2005-11-09 17:25:55 +00001586 r->variables[code->index].not_found = 0;
1587 r->variables[code->index].data = e->sp->data;
Igor Sysoev45656b42008-12-10 14:48:04 +00001588
1589#if (NGX_DEBUG)
1590 {
1591 ngx_http_variable_t *v;
1592 ngx_http_core_main_conf_t *cmcf;
1593
1594 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1595
1596 v = cmcf->variables.elts;
1597
1598 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1599 "http script set $%V", &v[code->index].name);
1600 }
1601#endif
Igor Sysoev899b44e2005-05-12 14:58:06 +00001602}
1603
1604
1605void
Igor Sysoev7bdb7202006-04-19 15:30:56 +00001606ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e)
1607{
1608 ngx_http_script_var_handler_code_t *code;
1609
1610 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1611 "http script set var handler");
1612
1613 code = (ngx_http_script_var_handler_code_t *) e->ip;
1614
1615 e->ip += sizeof(ngx_http_script_var_handler_code_t);
1616
1617 e->sp--;
1618
1619 code->handler(e->request, e->sp, code->data);
1620}
1621
1622
1623void
Igor Sysoev899b44e2005-05-12 14:58:06 +00001624ngx_http_script_var_code(ngx_http_script_engine_t *e)
1625{
1626 ngx_http_variable_value_t *value;
1627 ngx_http_script_var_code_t *code;
1628
1629 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1630 "http script var");
1631
1632 code = (ngx_http_script_var_code_t *) e->ip;
1633
1634 e->ip += sizeof(ngx_http_script_var_code_t);
1635
Igor Sysoev09c684b2005-11-09 17:25:55 +00001636 value = ngx_http_get_flushed_variable(e->request, code->index);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001637
Igor Sysoev09c684b2005-11-09 17:25:55 +00001638 if (value && !value->not_found) {
1639 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
Igor Sysoev0d4b3722007-08-20 09:57:19 +00001640 "http script var: \"%v\"", value);
Igor Sysoev09c684b2005-11-09 17:25:55 +00001641
Igor Sysoevf6e1fe32005-10-04 10:38:53 +00001642 *e->sp = *value;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001643 e->sp++;
1644
1645 return;
1646 }
1647
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001648 *e->sp = ngx_http_variable_null_value;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001649 e->sp++;
1650}
1651
1652
1653void
1654ngx_http_script_nop_code(ngx_http_script_engine_t *e)
1655{
1656 e->ip += sizeof(uintptr_t);
Igor Sysoev7578ec92003-06-02 15:24:30 +00001657}