1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_stream.h>
11
12
13 static ngx_int_t ngx_stream_script_init_arrays(
14 ngx_stream_script_compile_t *sc);
15 static ngx_int_t ngx_stream_script_done(ngx_stream_script_compile_t *sc);
16 static ngx_int_t ngx_stream_script_add_copy_code(
17 ngx_stream_script_compile_t *sc, ngx_str_t *value, ngx_uint_t last);
18 static ngx_int_t ngx_stream_script_add_var_code(
19 ngx_stream_script_compile_t *sc, ngx_str_t *name);
20 #if (NGX_PCRE)
21 static ngx_int_t ngx_stream_script_add_capture_code(
22 ngx_stream_script_compile_t *sc, ngx_uint_t n);
23 #endif
24 static ngx_int_t ngx_stream_script_add_full_name_code(
25 ngx_stream_script_compile_t *sc);
26 static size_t ngx_stream_script_full_name_len_code(
27 ngx_stream_script_engine_t *e);
28 static void ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e);
29
30
31 #define ngx_stream_script_exit (u_char *) &ngx_stream_script_exit_code
32
33 static uintptr_t ngx_stream_script_exit_code = (uintptr_t) NULL;
34
35
36 void
ngx_stream_script_flush_complex_value(ngx_stream_session_t * s,ngx_stream_complex_value_t * val)37 ngx_stream_script_flush_complex_value(ngx_stream_session_t *s,
38 ngx_stream_complex_value_t *val)
39 {
40 ngx_uint_t *index;
41
42 index = val->flushes;
43
44 if (index) {
45 while (*index != (ngx_uint_t) -1) {
46
47 if (s->variables[*index].no_cacheable) {
48 s->variables[*index].valid = 0;
49 s->variables[*index].not_found = 0;
50 }
51
52 index++;
53 }
54 }
55 }
56
57
58 ngx_int_t
ngx_stream_complex_value(ngx_stream_session_t * s,ngx_stream_complex_value_t * val,ngx_str_t * value)59 ngx_stream_complex_value(ngx_stream_session_t *s,
60 ngx_stream_complex_value_t *val, ngx_str_t *value)
61 {
62 size_t len;
63 ngx_stream_script_code_pt code;
64 ngx_stream_script_engine_t e;
65 ngx_stream_script_len_code_pt lcode;
66
67 if (val->lengths == NULL) {
68 *value = val->value;
69 return NGX_OK;
70 }
71
72 ngx_stream_script_flush_complex_value(s, val);
73
74 ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
75
76 e.ip = val->lengths;
77 e.session = s;
78 e.flushed = 1;
79
80 len = 0;
81
82 while (*(uintptr_t *) e.ip) {
83 lcode = *(ngx_stream_script_len_code_pt *) e.ip;
84 len += lcode(&e);
85 }
86
87 value->len = len;
88 value->data = ngx_pnalloc(s->connection->pool, len);
89 if (value->data == NULL) {
90 return NGX_ERROR;
91 }
92
93 e.ip = val->values;
94 e.pos = value->data;
95 e.buf = *value;
96
97 while (*(uintptr_t *) e.ip) {
98 code = *(ngx_stream_script_code_pt *) e.ip;
99 code((ngx_stream_script_engine_t *) &e);
100 }
101
102 *value = e.buf;
103
104 return NGX_OK;
105 }
106
107
108 ngx_int_t
ngx_stream_compile_complex_value(ngx_stream_compile_complex_value_t * ccv)109 ngx_stream_compile_complex_value(ngx_stream_compile_complex_value_t *ccv)
110 {
111 ngx_str_t *v;
112 ngx_uint_t i, n, nv, nc;
113 ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
114 ngx_stream_script_compile_t sc;
115
116 v = ccv->value;
117
118 nv = 0;
119 nc = 0;
120
121 for (i = 0; i < v->len; i++) {
122 if (v->data[i] == '$') {
123 if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
124 nc++;
125
126 } else {
127 nv++;
128 }
129 }
130 }
131
132 if ((v->len == 0 || v->data[0] != '$')
133 && (ccv->conf_prefix || ccv->root_prefix))
134 {
135 if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
136 return NGX_ERROR;
137 }
138
139 ccv->conf_prefix = 0;
140 ccv->root_prefix = 0;
141 }
142
143 ccv->complex_value->value = *v;
144 ccv->complex_value->flushes = NULL;
145 ccv->complex_value->lengths = NULL;
146 ccv->complex_value->values = NULL;
147
148 if (nv == 0 && nc == 0) {
149 return NGX_OK;
150 }
151
152 n = nv + 1;
153
154 if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
155 != NGX_OK)
156 {
157 return NGX_ERROR;
158 }
159
160 n = nv * (2 * sizeof(ngx_stream_script_copy_code_t)
161 + sizeof(ngx_stream_script_var_code_t))
162 + sizeof(uintptr_t);
163
164 if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
165 return NGX_ERROR;
166 }
167
168 n = (nv * (2 * sizeof(ngx_stream_script_copy_code_t)
169 + sizeof(ngx_stream_script_var_code_t))
170 + sizeof(uintptr_t)
171 + v->len
172 + sizeof(uintptr_t) - 1)
173 & ~(sizeof(uintptr_t) - 1);
174
175 if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
176 return NGX_ERROR;
177 }
178
179 pf = &flushes;
180 pl = &lengths;
181 pv = &values;
182
183 ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t));
184
185 sc.cf = ccv->cf;
186 sc.source = v;
187 sc.flushes = &pf;
188 sc.lengths = &pl;
189 sc.values = &pv;
190 sc.complete_lengths = 1;
191 sc.complete_values = 1;
192 sc.zero = ccv->zero;
193 sc.conf_prefix = ccv->conf_prefix;
194 sc.root_prefix = ccv->root_prefix;
195
196 if (ngx_stream_script_compile(&sc) != NGX_OK) {
197 return NGX_ERROR;
198 }
199
200 if (flushes.nelts) {
201 ccv->complex_value->flushes = flushes.elts;
202 ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
203 }
204
205 ccv->complex_value->lengths = lengths.elts;
206 ccv->complex_value->values = values.elts;
207
208 return NGX_OK;
209 }
210
211
212 char *
ngx_stream_set_complex_value_slot(ngx_conf_t * cf,ngx_command_t * cmd,void * conf)213 ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
214 void *conf)
215 {
216 char *p = conf;
217
218 ngx_str_t *value;
219 ngx_stream_complex_value_t **cv;
220 ngx_stream_compile_complex_value_t ccv;
221
222 cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
223
224 if (*cv != NULL) {
225 return "is duplicate";
226 }
227
228 *cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
229 if (*cv == NULL) {
230 return NGX_CONF_ERROR;
231 }
232
233 value = cf->args->elts;
234
235 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
236
237 ccv.cf = cf;
238 ccv.value = &value[1];
239 ccv.complex_value = *cv;
240
241 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
242 return NGX_CONF_ERROR;
243 }
244
245 return NGX_CONF_OK;
246 }
247
248
249 ngx_uint_t
ngx_stream_script_variables_count(ngx_str_t * value)250 ngx_stream_script_variables_count(ngx_str_t *value)
251 {
252 ngx_uint_t i, n;
253
254 for (n = 0, i = 0; i < value->len; i++) {
255 if (value->data[i] == '$') {
256 n++;
257 }
258 }
259
260 return n;
261 }
262
263
264 ngx_int_t
ngx_stream_script_compile(ngx_stream_script_compile_t * sc)265 ngx_stream_script_compile(ngx_stream_script_compile_t *sc)
266 {
267 u_char ch;
268 ngx_str_t name;
269 ngx_uint_t i, bracket;
270
271 if (ngx_stream_script_init_arrays(sc) != NGX_OK) {
272 return NGX_ERROR;
273 }
274
275 for (i = 0; i < sc->source->len; /* void */ ) {
276
277 name.len = 0;
278
279 if (sc->source->data[i] == '$') {
280
281 if (++i == sc->source->len) {
282 goto invalid_variable;
283 }
284
285 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
286 #if (NGX_PCRE)
287 ngx_uint_t n;
288
289 n = sc->source->data[i] - '0';
290
291 if (ngx_stream_script_add_capture_code(sc, n) != NGX_OK) {
292 return NGX_ERROR;
293 }
294
295 i++;
296
297 continue;
298 #else
299 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
300 "using variable \"$%c\" requires "
301 "PCRE library", sc->source->data[i]);
302 return NGX_ERROR;
303 #endif
304 }
305
306 if (sc->source->data[i] == '{') {
307 bracket = 1;
308
309 if (++i == sc->source->len) {
310 goto invalid_variable;
311 }
312
313 name.data = &sc->source->data[i];
314
315 } else {
316 bracket = 0;
317 name.data = &sc->source->data[i];
318 }
319
320 for ( /* void */ ; i < sc->source->len; i++, name.len++) {
321 ch = sc->source->data[i];
322
323 if (ch == '}' && bracket) {
324 i++;
325 bracket = 0;
326 break;
327 }
328
329 if ((ch >= 'A' && ch <= 'Z')
330 || (ch >= 'a' && ch <= 'z')
331 || (ch >= '0' && ch <= '9')
332 || ch == '_')
333 {
334 continue;
335 }
336
337 break;
338 }
339
340 if (bracket) {
341 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
342 "the closing bracket in \"%V\" "
343 "variable is missing", &name);
344 return NGX_ERROR;
345 }
346
347 if (name.len == 0) {
348 goto invalid_variable;
349 }
350
351 sc->variables++;
352
353 if (ngx_stream_script_add_var_code(sc, &name) != NGX_OK) {
354 return NGX_ERROR;
355 }
356
357 continue;
358 }
359
360 name.data = &sc->source->data[i];
361
362 while (i < sc->source->len) {
363
364 if (sc->source->data[i] == '$') {
365 break;
366 }
367
368 i++;
369 name.len++;
370 }
371
372 sc->size += name.len;
373
374 if (ngx_stream_script_add_copy_code(sc, &name, (i == sc->source->len))
375 != NGX_OK)
376 {
377 return NGX_ERROR;
378 }
379 }
380
381 return ngx_stream_script_done(sc);
382
383 invalid_variable:
384
385 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
386
387 return NGX_ERROR;
388 }
389
390
391 u_char *
ngx_stream_script_run(ngx_stream_session_t * s,ngx_str_t * value,void * code_lengths,size_t len,void * code_values)392 ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
393 void *code_lengths, size_t len, void *code_values)
394 {
395 ngx_uint_t i;
396 ngx_stream_script_code_pt code;
397 ngx_stream_script_engine_t e;
398 ngx_stream_core_main_conf_t *cmcf;
399 ngx_stream_script_len_code_pt lcode;
400
401 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
402
403 for (i = 0; i < cmcf->variables.nelts; i++) {
404 if (s->variables[i].no_cacheable) {
405 s->variables[i].valid = 0;
406 s->variables[i].not_found = 0;
407 }
408 }
409
410 ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
411
412 e.ip = code_lengths;
413 e.session = s;
414 e.flushed = 1;
415
416 while (*(uintptr_t *) e.ip) {
417 lcode = *(ngx_stream_script_len_code_pt *) e.ip;
418 len += lcode(&e);
419 }
420
421
422 value->len = len;
423 value->data = ngx_pnalloc(s->connection->pool, len);
424 if (value->data == NULL) {
425 return NULL;
426 }
427
428 e.ip = code_values;
429 e.pos = value->data;
430
431 while (*(uintptr_t *) e.ip) {
432 code = *(ngx_stream_script_code_pt *) e.ip;
433 code((ngx_stream_script_engine_t *) &e);
434 }
435
436 return e.pos;
437 }
438
439
440 void
ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t * s,ngx_array_t * indices)441 ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s,
442 ngx_array_t *indices)
443 {
444 ngx_uint_t n, *index;
445
446 if (indices) {
447 index = indices->elts;
448 for (n = 0; n < indices->nelts; n++) {
449 if (s->variables[index[n]].no_cacheable) {
450 s->variables[index[n]].valid = 0;
451 s->variables[index[n]].not_found = 0;
452 }
453 }
454 }
455 }
456
457
458 static ngx_int_t
ngx_stream_script_init_arrays(ngx_stream_script_compile_t * sc)459 ngx_stream_script_init_arrays(ngx_stream_script_compile_t *sc)
460 {
461 ngx_uint_t n;
462
463 if (sc->flushes && *sc->flushes == NULL) {
464 n = sc->variables ? sc->variables : 1;
465 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
466 if (*sc->flushes == NULL) {
467 return NGX_ERROR;
468 }
469 }
470
471 if (*sc->lengths == NULL) {
472 n = sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
473 + sizeof(ngx_stream_script_var_code_t))
474 + sizeof(uintptr_t);
475
476 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
477 if (*sc->lengths == NULL) {
478 return NGX_ERROR;
479 }
480 }
481
482 if (*sc->values == NULL) {
483 n = (sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
484 + sizeof(ngx_stream_script_var_code_t))
485 + sizeof(uintptr_t)
486 + sc->source->len
487 + sizeof(uintptr_t) - 1)
488 & ~(sizeof(uintptr_t) - 1);
489
490 *sc->values = ngx_array_create(sc->cf->pool, n, 1);
491 if (*sc->values == NULL) {
492 return NGX_ERROR;
493 }
494 }
495
496 sc->variables = 0;
497
498 return NGX_OK;
499 }
500
501
502 static ngx_int_t
ngx_stream_script_done(ngx_stream_script_compile_t * sc)503 ngx_stream_script_done(ngx_stream_script_compile_t *sc)
504 {
505 ngx_str_t zero;
506 uintptr_t *code;
507
508 if (sc->zero) {
509
510 zero.len = 1;
511 zero.data = (u_char *) "\0";
512
513 if (ngx_stream_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
514 return NGX_ERROR;
515 }
516 }
517
518 if (sc->conf_prefix || sc->root_prefix) {
519 if (ngx_stream_script_add_full_name_code(sc) != NGX_OK) {
520 return NGX_ERROR;
521 }
522 }
523
524 if (sc->complete_lengths) {
525 code = ngx_stream_script_add_code(*sc->lengths, sizeof(uintptr_t),
526 NULL);
527 if (code == NULL) {
528 return NGX_ERROR;
529 }
530
531 *code = (uintptr_t) NULL;
532 }
533
534 if (sc->complete_values) {
535 code = ngx_stream_script_add_code(*sc->values, sizeof(uintptr_t),
536 &sc->main);
537 if (code == NULL) {
538 return NGX_ERROR;
539 }
540
541 *code = (uintptr_t) NULL;
542 }
543
544 return NGX_OK;
545 }
546
547
548 void *
ngx_stream_script_add_code(ngx_array_t * codes,size_t size,void * code)549 ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code)
550 {
551 u_char *elts, **p;
552 void *new;
553
554 elts = codes->elts;
555
556 new = ngx_array_push_n(codes, size);
557 if (new == NULL) {
558 return NULL;
559 }
560
561 if (code) {
562 if (elts != codes->elts) {
563 p = code;
564 *p += (u_char *) codes->elts - elts;
565 }
566 }
567
568 return new;
569 }
570
571
572 static ngx_int_t
ngx_stream_script_add_copy_code(ngx_stream_script_compile_t * sc,ngx_str_t * value,ngx_uint_t last)573 ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc,
574 ngx_str_t *value, ngx_uint_t last)
575 {
576 u_char *p;
577 size_t size, len, zero;
578 ngx_stream_script_copy_code_t *code;
579
580 zero = (sc->zero && last);
581 len = value->len + zero;
582
583 code = ngx_stream_script_add_code(*sc->lengths,
584 sizeof(ngx_stream_script_copy_code_t),
585 NULL);
586 if (code == NULL) {
587 return NGX_ERROR;
588 }
589
590 code->code = (ngx_stream_script_code_pt) (void *)
591 ngx_stream_script_copy_len_code;
592 code->len = len;
593
594 size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
595 & ~(sizeof(uintptr_t) - 1);
596
597 code = ngx_stream_script_add_code(*sc->values, size, &sc->main);
598 if (code == NULL) {
599 return NGX_ERROR;
600 }
601
602 code->code = ngx_stream_script_copy_code;
603 code->len = len;
604
605 p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t),
606 value->data, value->len);
607
608 if (zero) {
609 *p = '\0';
610 sc->zero = 0;
611 }
612
613 return NGX_OK;
614 }
615
616
617 size_t
ngx_stream_script_copy_len_code(ngx_stream_script_engine_t * e)618 ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e)
619 {
620 ngx_stream_script_copy_code_t *code;
621
622 code = (ngx_stream_script_copy_code_t *) e->ip;
623
624 e->ip += sizeof(ngx_stream_script_copy_code_t);
625
626 return code->len;
627 }
628
629
630 void
ngx_stream_script_copy_code(ngx_stream_script_engine_t * e)631 ngx_stream_script_copy_code(ngx_stream_script_engine_t *e)
632 {
633 u_char *p;
634 ngx_stream_script_copy_code_t *code;
635
636 code = (ngx_stream_script_copy_code_t *) e->ip;
637
638 p = e->pos;
639
640 if (!e->skip) {
641 e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t),
642 code->len);
643 }
644
645 e->ip += sizeof(ngx_stream_script_copy_code_t)
646 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
647
648 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
649 "stream script copy: \"%*s\"", e->pos - p, p);
650 }
651
652
653 static ngx_int_t
ngx_stream_script_add_var_code(ngx_stream_script_compile_t * sc,ngx_str_t * name)654 ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name)
655 {
656 ngx_int_t index, *p;
657 ngx_stream_script_var_code_t *code;
658
659 index = ngx_stream_get_variable_index(sc->cf, name);
660
661 if (index == NGX_ERROR) {
662 return NGX_ERROR;
663 }
664
665 if (sc->flushes) {
666 p = ngx_array_push(*sc->flushes);
667 if (p == NULL) {
668 return NGX_ERROR;
669 }
670
671 *p = index;
672 }
673
674 code = ngx_stream_script_add_code(*sc->lengths,
675 sizeof(ngx_stream_script_var_code_t),
676 NULL);
677 if (code == NULL) {
678 return NGX_ERROR;
679 }
680
681 code->code = (ngx_stream_script_code_pt) (void *)
682 ngx_stream_script_copy_var_len_code;
683 code->index = (uintptr_t) index;
684
685 code = ngx_stream_script_add_code(*sc->values,
686 sizeof(ngx_stream_script_var_code_t),
687 &sc->main);
688 if (code == NULL) {
689 return NGX_ERROR;
690 }
691
692 code->code = ngx_stream_script_copy_var_code;
693 code->index = (uintptr_t) index;
694
695 return NGX_OK;
696 }
697
698
699 size_t
ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t * e)700 ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e)
701 {
702 ngx_stream_variable_value_t *value;
703 ngx_stream_script_var_code_t *code;
704
705 code = (ngx_stream_script_var_code_t *) e->ip;
706
707 e->ip += sizeof(ngx_stream_script_var_code_t);
708
709 if (e->flushed) {
710 value = ngx_stream_get_indexed_variable(e->session, code->index);
711
712 } else {
713 value = ngx_stream_get_flushed_variable(e->session, code->index);
714 }
715
716 if (value && !value->not_found) {
717 return value->len;
718 }
719
720 return 0;
721 }
722
723
724 void
ngx_stream_script_copy_var_code(ngx_stream_script_engine_t * e)725 ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e)
726 {
727 u_char *p;
728 ngx_stream_variable_value_t *value;
729 ngx_stream_script_var_code_t *code;
730
731 code = (ngx_stream_script_var_code_t *) e->ip;
732
733 e->ip += sizeof(ngx_stream_script_var_code_t);
734
735 if (!e->skip) {
736
737 if (e->flushed) {
738 value = ngx_stream_get_indexed_variable(e->session, code->index);
739
740 } else {
741 value = ngx_stream_get_flushed_variable(e->session, code->index);
742 }
743
744 if (value && !value->not_found) {
745 p = e->pos;
746 e->pos = ngx_copy(p, value->data, value->len);
747
748 ngx_log_debug2(NGX_LOG_DEBUG_STREAM,
749 e->session->connection->log, 0,
750 "stream script var: \"%*s\"", e->pos - p, p);
751 }
752 }
753 }
754
755
756 #if (NGX_PCRE)
757
758 static ngx_int_t
ngx_stream_script_add_capture_code(ngx_stream_script_compile_t * sc,ngx_uint_t n)759 ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc,
760 ngx_uint_t n)
761 {
762 ngx_stream_script_copy_capture_code_t *code;
763
764 code = ngx_stream_script_add_code(*sc->lengths,
765 sizeof(ngx_stream_script_copy_capture_code_t),
766 NULL);
767 if (code == NULL) {
768 return NGX_ERROR;
769 }
770
771 code->code = (ngx_stream_script_code_pt) (void *)
772 ngx_stream_script_copy_capture_len_code;
773 code->n = 2 * n;
774
775
776 code = ngx_stream_script_add_code(*sc->values,
777 sizeof(ngx_stream_script_copy_capture_code_t),
778 &sc->main);
779 if (code == NULL) {
780 return NGX_ERROR;
781 }
782
783 code->code = ngx_stream_script_copy_capture_code;
784 code->n = 2 * n;
785
786 if (sc->ncaptures < n) {
787 sc->ncaptures = n;
788 }
789
790 return NGX_OK;
791 }
792
793
794 size_t
ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t * e)795 ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e)
796 {
797 int *cap;
798 ngx_uint_t n;
799 ngx_stream_session_t *s;
800 ngx_stream_script_copy_capture_code_t *code;
801
802 s = e->session;
803
804 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
805
806 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
807
808 n = code->n;
809
810 if (n < s->ncaptures) {
811 cap = s->captures;
812 return cap[n + 1] - cap[n];
813 }
814
815 return 0;
816 }
817
818
819 void
ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t * e)820 ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e)
821 {
822 int *cap;
823 u_char *p, *pos;
824 ngx_uint_t n;
825 ngx_stream_session_t *s;
826 ngx_stream_script_copy_capture_code_t *code;
827
828 s = e->session;
829
830 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
831
832 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
833
834 n = code->n;
835
836 pos = e->pos;
837
838 if (n < s->ncaptures) {
839 cap = s->captures;
840 p = s->captures_data;
841 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
842 }
843
844 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
845 "stream script capture: \"%*s\"", e->pos - pos, pos);
846 }
847
848 #endif
849
850
851 static ngx_int_t
ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t * sc)852 ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc)
853 {
854 ngx_stream_script_full_name_code_t *code;
855
856 code = ngx_stream_script_add_code(*sc->lengths,
857 sizeof(ngx_stream_script_full_name_code_t),
858 NULL);
859 if (code == NULL) {
860 return NGX_ERROR;
861 }
862
863 code->code = (ngx_stream_script_code_pt) (void *)
864 ngx_stream_script_full_name_len_code;
865 code->conf_prefix = sc->conf_prefix;
866
867 code = ngx_stream_script_add_code(*sc->values,
868 sizeof(ngx_stream_script_full_name_code_t), &sc->main);
869 if (code == NULL) {
870 return NGX_ERROR;
871 }
872
873 code->code = ngx_stream_script_full_name_code;
874 code->conf_prefix = sc->conf_prefix;
875
876 return NGX_OK;
877 }
878
879
880 static size_t
ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t * e)881 ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e)
882 {
883 ngx_stream_script_full_name_code_t *code;
884
885 code = (ngx_stream_script_full_name_code_t *) e->ip;
886
887 e->ip += sizeof(ngx_stream_script_full_name_code_t);
888
889 return code->conf_prefix ? ngx_cycle->conf_prefix.len:
890 ngx_cycle->prefix.len;
891 }
892
893
894 static void
ngx_stream_script_full_name_code(ngx_stream_script_engine_t * e)895 ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e)
896 {
897 ngx_stream_script_full_name_code_t *code;
898
899 ngx_str_t value, *prefix;
900
901 code = (ngx_stream_script_full_name_code_t *) e->ip;
902
903 value.data = e->buf.data;
904 value.len = e->pos - e->buf.data;
905
906 prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
907 (ngx_str_t *) &ngx_cycle->prefix;
908
909 if (ngx_get_full_name(e->session->connection->pool, prefix, &value)
910 != NGX_OK)
911 {
912 e->ip = ngx_stream_script_exit;
913 return;
914 }
915
916 e->buf = value;
917
918 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
919 "stream script fullname: \"%V\"", &value);
920
921 e->ip += sizeof(ngx_stream_script_full_name_code_t);
922 }
923