Mercurial > hg > nginx-quic
comparison src/stream/ngx_stream_script.c @ 6607:c70b7f4537e1
Stream: variables and script.
This is a port of corresponding http code with unrelated features excluded.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 04 Jul 2016 16:37:36 +0300 |
parents | |
children | af642539cd53 |
comparison
equal
deleted
inserted
replaced
6606:2f41d383c9c7 | 6607:c70b7f4537e1 |
---|---|
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 | |
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 | |
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 | |
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 * | |
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 "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 | |
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 | |
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 (NGX_PCRE) | |
286 { | |
287 ngx_uint_t n; | |
288 | |
289 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { | |
290 | |
291 n = sc->source->data[i] - '0'; | |
292 | |
293 if (ngx_stream_script_add_capture_code(sc, n) != NGX_OK) { | |
294 return NGX_ERROR; | |
295 } | |
296 | |
297 i++; | |
298 | |
299 continue; | |
300 } | |
301 } | |
302 #endif | |
303 | |
304 if (sc->source->data[i] == '{') { | |
305 bracket = 1; | |
306 | |
307 if (++i == sc->source->len) { | |
308 goto invalid_variable; | |
309 } | |
310 | |
311 name.data = &sc->source->data[i]; | |
312 | |
313 } else { | |
314 bracket = 0; | |
315 name.data = &sc->source->data[i]; | |
316 } | |
317 | |
318 for ( /* void */ ; i < sc->source->len; i++, name.len++) { | |
319 ch = sc->source->data[i]; | |
320 | |
321 if (ch == '}' && bracket) { | |
322 i++; | |
323 bracket = 0; | |
324 break; | |
325 } | |
326 | |
327 if ((ch >= 'A' && ch <= 'Z') | |
328 || (ch >= 'a' && ch <= 'z') | |
329 || (ch >= '0' && ch <= '9') | |
330 || ch == '_') | |
331 { | |
332 continue; | |
333 } | |
334 | |
335 break; | |
336 } | |
337 | |
338 if (bracket) { | |
339 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, | |
340 "the closing bracket in \"%V\" " | |
341 "variable is missing", &name); | |
342 return NGX_ERROR; | |
343 } | |
344 | |
345 if (name.len == 0) { | |
346 goto invalid_variable; | |
347 } | |
348 | |
349 sc->variables++; | |
350 | |
351 if (ngx_stream_script_add_var_code(sc, &name) != NGX_OK) { | |
352 return NGX_ERROR; | |
353 } | |
354 | |
355 continue; | |
356 } | |
357 | |
358 name.data = &sc->source->data[i]; | |
359 | |
360 while (i < sc->source->len) { | |
361 | |
362 if (sc->source->data[i] == '$') { | |
363 break; | |
364 } | |
365 | |
366 i++; | |
367 name.len++; | |
368 } | |
369 | |
370 sc->size += name.len; | |
371 | |
372 if (ngx_stream_script_add_copy_code(sc, &name, (i == sc->source->len)) | |
373 != NGX_OK) | |
374 { | |
375 return NGX_ERROR; | |
376 } | |
377 } | |
378 | |
379 return ngx_stream_script_done(sc); | |
380 | |
381 invalid_variable: | |
382 | |
383 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name"); | |
384 | |
385 return NGX_ERROR; | |
386 } | |
387 | |
388 | |
389 static ngx_int_t | |
390 ngx_stream_script_init_arrays(ngx_stream_script_compile_t *sc) | |
391 { | |
392 ngx_uint_t n; | |
393 | |
394 if (sc->flushes && *sc->flushes == NULL) { | |
395 n = sc->variables ? sc->variables : 1; | |
396 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); | |
397 if (*sc->flushes == NULL) { | |
398 return NGX_ERROR; | |
399 } | |
400 } | |
401 | |
402 if (*sc->lengths == NULL) { | |
403 n = sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t) | |
404 + sizeof(ngx_stream_script_var_code_t)) | |
405 + sizeof(uintptr_t); | |
406 | |
407 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1); | |
408 if (*sc->lengths == NULL) { | |
409 return NGX_ERROR; | |
410 } | |
411 } | |
412 | |
413 if (*sc->values == NULL) { | |
414 n = (sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t) | |
415 + sizeof(ngx_stream_script_var_code_t)) | |
416 + sizeof(uintptr_t) | |
417 + sc->source->len | |
418 + sizeof(uintptr_t) - 1) | |
419 & ~(sizeof(uintptr_t) - 1); | |
420 | |
421 *sc->values = ngx_array_create(sc->cf->pool, n, 1); | |
422 if (*sc->values == NULL) { | |
423 return NGX_ERROR; | |
424 } | |
425 } | |
426 | |
427 sc->variables = 0; | |
428 | |
429 return NGX_OK; | |
430 } | |
431 | |
432 | |
433 static ngx_int_t | |
434 ngx_stream_script_done(ngx_stream_script_compile_t *sc) | |
435 { | |
436 ngx_str_t zero; | |
437 uintptr_t *code; | |
438 | |
439 if (sc->zero) { | |
440 | |
441 zero.len = 1; | |
442 zero.data = (u_char *) "\0"; | |
443 | |
444 if (ngx_stream_script_add_copy_code(sc, &zero, 0) != NGX_OK) { | |
445 return NGX_ERROR; | |
446 } | |
447 } | |
448 | |
449 if (sc->conf_prefix || sc->root_prefix) { | |
450 if (ngx_stream_script_add_full_name_code(sc) != NGX_OK) { | |
451 return NGX_ERROR; | |
452 } | |
453 } | |
454 | |
455 if (sc->complete_lengths) { | |
456 code = ngx_stream_script_add_code(*sc->lengths, sizeof(uintptr_t), | |
457 NULL); | |
458 if (code == NULL) { | |
459 return NGX_ERROR; | |
460 } | |
461 | |
462 *code = (uintptr_t) NULL; | |
463 } | |
464 | |
465 if (sc->complete_values) { | |
466 code = ngx_stream_script_add_code(*sc->values, sizeof(uintptr_t), | |
467 &sc->main); | |
468 if (code == NULL) { | |
469 return NGX_ERROR; | |
470 } | |
471 | |
472 *code = (uintptr_t) NULL; | |
473 } | |
474 | |
475 return NGX_OK; | |
476 } | |
477 | |
478 | |
479 void * | |
480 ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code) | |
481 { | |
482 u_char *elts, **p; | |
483 void *new; | |
484 | |
485 elts = codes->elts; | |
486 | |
487 new = ngx_array_push_n(codes, size); | |
488 if (new == NULL) { | |
489 return NULL; | |
490 } | |
491 | |
492 if (code) { | |
493 if (elts != codes->elts) { | |
494 p = code; | |
495 *p += (u_char *) codes->elts - elts; | |
496 } | |
497 } | |
498 | |
499 return new; | |
500 } | |
501 | |
502 | |
503 static ngx_int_t | |
504 ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc, | |
505 ngx_str_t *value, ngx_uint_t last) | |
506 { | |
507 u_char *p; | |
508 size_t size, len, zero; | |
509 ngx_stream_script_copy_code_t *code; | |
510 | |
511 zero = (sc->zero && last); | |
512 len = value->len + zero; | |
513 | |
514 code = ngx_stream_script_add_code(*sc->lengths, | |
515 sizeof(ngx_stream_script_copy_code_t), | |
516 NULL); | |
517 if (code == NULL) { | |
518 return NGX_ERROR; | |
519 } | |
520 | |
521 code->code = (ngx_stream_script_code_pt) ngx_stream_script_copy_len_code; | |
522 code->len = len; | |
523 | |
524 size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1) | |
525 & ~(sizeof(uintptr_t) - 1); | |
526 | |
527 code = ngx_stream_script_add_code(*sc->values, size, &sc->main); | |
528 if (code == NULL) { | |
529 return NGX_ERROR; | |
530 } | |
531 | |
532 code->code = ngx_stream_script_copy_code; | |
533 code->len = len; | |
534 | |
535 p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t), | |
536 value->data, value->len); | |
537 | |
538 if (zero) { | |
539 *p = '\0'; | |
540 sc->zero = 0; | |
541 } | |
542 | |
543 return NGX_OK; | |
544 } | |
545 | |
546 | |
547 size_t | |
548 ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e) | |
549 { | |
550 ngx_stream_script_copy_code_t *code; | |
551 | |
552 code = (ngx_stream_script_copy_code_t *) e->ip; | |
553 | |
554 e->ip += sizeof(ngx_stream_script_copy_code_t); | |
555 | |
556 return code->len; | |
557 } | |
558 | |
559 | |
560 void | |
561 ngx_stream_script_copy_code(ngx_stream_script_engine_t *e) | |
562 { | |
563 u_char *p; | |
564 ngx_stream_script_copy_code_t *code; | |
565 | |
566 code = (ngx_stream_script_copy_code_t *) e->ip; | |
567 | |
568 p = e->pos; | |
569 | |
570 if (!e->skip) { | |
571 e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t), | |
572 code->len); | |
573 } | |
574 | |
575 e->ip += sizeof(ngx_stream_script_copy_code_t) | |
576 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); | |
577 | |
578 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, | |
579 "stream script copy: \"%*s\"", e->pos - p, p); | |
580 } | |
581 | |
582 | |
583 static ngx_int_t | |
584 ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name) | |
585 { | |
586 ngx_int_t index, *p; | |
587 ngx_stream_script_var_code_t *code; | |
588 | |
589 index = ngx_stream_get_variable_index(sc->cf, name); | |
590 | |
591 if (index == NGX_ERROR) { | |
592 return NGX_ERROR; | |
593 } | |
594 | |
595 if (sc->flushes) { | |
596 p = ngx_array_push(*sc->flushes); | |
597 if (p == NULL) { | |
598 return NGX_ERROR; | |
599 } | |
600 | |
601 *p = index; | |
602 } | |
603 | |
604 code = ngx_stream_script_add_code(*sc->lengths, | |
605 sizeof(ngx_stream_script_var_code_t), | |
606 NULL); | |
607 if (code == NULL) { | |
608 return NGX_ERROR; | |
609 } | |
610 | |
611 code->code = (ngx_stream_script_code_pt) | |
612 ngx_stream_script_copy_var_len_code; | |
613 code->index = (uintptr_t) index; | |
614 | |
615 code = ngx_stream_script_add_code(*sc->values, | |
616 sizeof(ngx_stream_script_var_code_t), | |
617 &sc->main); | |
618 if (code == NULL) { | |
619 return NGX_ERROR; | |
620 } | |
621 | |
622 code->code = ngx_stream_script_copy_var_code; | |
623 code->index = (uintptr_t) index; | |
624 | |
625 return NGX_OK; | |
626 } | |
627 | |
628 | |
629 size_t | |
630 ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e) | |
631 { | |
632 ngx_stream_variable_value_t *value; | |
633 ngx_stream_script_var_code_t *code; | |
634 | |
635 code = (ngx_stream_script_var_code_t *) e->ip; | |
636 | |
637 e->ip += sizeof(ngx_stream_script_var_code_t); | |
638 | |
639 if (e->flushed) { | |
640 value = ngx_stream_get_indexed_variable(e->session, code->index); | |
641 | |
642 } else { | |
643 value = ngx_stream_get_flushed_variable(e->session, code->index); | |
644 } | |
645 | |
646 if (value && !value->not_found) { | |
647 return value->len; | |
648 } | |
649 | |
650 return 0; | |
651 } | |
652 | |
653 | |
654 void | |
655 ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e) | |
656 { | |
657 u_char *p; | |
658 ngx_stream_variable_value_t *value; | |
659 ngx_stream_script_var_code_t *code; | |
660 | |
661 code = (ngx_stream_script_var_code_t *) e->ip; | |
662 | |
663 e->ip += sizeof(ngx_stream_script_var_code_t); | |
664 | |
665 if (!e->skip) { | |
666 | |
667 if (e->flushed) { | |
668 value = ngx_stream_get_indexed_variable(e->session, code->index); | |
669 | |
670 } else { | |
671 value = ngx_stream_get_flushed_variable(e->session, code->index); | |
672 } | |
673 | |
674 if (value && !value->not_found) { | |
675 p = e->pos; | |
676 e->pos = ngx_copy(p, value->data, value->len); | |
677 | |
678 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, | |
679 e->session->connection->log, 0, | |
680 "stream script var: \"%*s\"", e->pos - p, p); | |
681 } | |
682 } | |
683 } | |
684 | |
685 | |
686 #if (NGX_PCRE) | |
687 | |
688 static ngx_int_t | |
689 ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc, | |
690 ngx_uint_t n) | |
691 { | |
692 ngx_stream_script_copy_capture_code_t *code; | |
693 | |
694 code = ngx_stream_script_add_code(*sc->lengths, | |
695 sizeof(ngx_stream_script_copy_capture_code_t), | |
696 NULL); | |
697 if (code == NULL) { | |
698 return NGX_ERROR; | |
699 } | |
700 | |
701 code->code = (ngx_stream_script_code_pt) | |
702 ngx_stream_script_copy_capture_len_code; | |
703 code->n = 2 * n; | |
704 | |
705 | |
706 code = ngx_stream_script_add_code(*sc->values, | |
707 sizeof(ngx_stream_script_copy_capture_code_t), | |
708 &sc->main); | |
709 if (code == NULL) { | |
710 return NGX_ERROR; | |
711 } | |
712 | |
713 code->code = ngx_stream_script_copy_capture_code; | |
714 code->n = 2 * n; | |
715 | |
716 if (sc->ncaptures < n) { | |
717 sc->ncaptures = n; | |
718 } | |
719 | |
720 return NGX_OK; | |
721 } | |
722 | |
723 | |
724 size_t | |
725 ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e) | |
726 { | |
727 int *cap; | |
728 ngx_uint_t n; | |
729 ngx_stream_session_t *s; | |
730 ngx_stream_script_copy_capture_code_t *code; | |
731 | |
732 s = e->session; | |
733 | |
734 code = (ngx_stream_script_copy_capture_code_t *) e->ip; | |
735 | |
736 e->ip += sizeof(ngx_stream_script_copy_capture_code_t); | |
737 | |
738 n = code->n; | |
739 | |
740 if (n < s->ncaptures) { | |
741 cap = s->captures; | |
742 return cap[n + 1] - cap[n]; | |
743 } | |
744 | |
745 return 0; | |
746 } | |
747 | |
748 | |
749 void | |
750 ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e) | |
751 { | |
752 int *cap; | |
753 u_char *p, *pos; | |
754 ngx_uint_t n; | |
755 ngx_stream_session_t *s; | |
756 ngx_stream_script_copy_capture_code_t *code; | |
757 | |
758 s = e->session; | |
759 | |
760 code = (ngx_stream_script_copy_capture_code_t *) e->ip; | |
761 | |
762 e->ip += sizeof(ngx_stream_script_copy_capture_code_t); | |
763 | |
764 n = code->n; | |
765 | |
766 pos = e->pos; | |
767 | |
768 if (n < s->ncaptures) { | |
769 cap = s->captures; | |
770 p = s->captures_data; | |
771 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]); | |
772 } | |
773 | |
774 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, | |
775 "stream script capture: \"%*s\"", e->pos - pos, pos); | |
776 } | |
777 | |
778 #endif | |
779 | |
780 | |
781 static ngx_int_t | |
782 ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc) | |
783 { | |
784 ngx_stream_script_full_name_code_t *code; | |
785 | |
786 code = ngx_stream_script_add_code(*sc->lengths, | |
787 sizeof(ngx_stream_script_full_name_code_t), | |
788 NULL); | |
789 if (code == NULL) { | |
790 return NGX_ERROR; | |
791 } | |
792 | |
793 code->code = (ngx_stream_script_code_pt) | |
794 ngx_stream_script_full_name_len_code; | |
795 code->conf_prefix = sc->conf_prefix; | |
796 | |
797 code = ngx_stream_script_add_code(*sc->values, | |
798 sizeof(ngx_stream_script_full_name_code_t), &sc->main); | |
799 if (code == NULL) { | |
800 return NGX_ERROR; | |
801 } | |
802 | |
803 code->code = ngx_stream_script_full_name_code; | |
804 code->conf_prefix = sc->conf_prefix; | |
805 | |
806 return NGX_OK; | |
807 } | |
808 | |
809 | |
810 static size_t | |
811 ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e) | |
812 { | |
813 ngx_stream_script_full_name_code_t *code; | |
814 | |
815 code = (ngx_stream_script_full_name_code_t *) e->ip; | |
816 | |
817 e->ip += sizeof(ngx_stream_script_full_name_code_t); | |
818 | |
819 return code->conf_prefix ? ngx_cycle->conf_prefix.len: | |
820 ngx_cycle->prefix.len; | |
821 } | |
822 | |
823 | |
824 static void | |
825 ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e) | |
826 { | |
827 ngx_stream_script_full_name_code_t *code; | |
828 | |
829 ngx_str_t value, *prefix; | |
830 | |
831 code = (ngx_stream_script_full_name_code_t *) e->ip; | |
832 | |
833 value.data = e->buf.data; | |
834 value.len = e->pos - e->buf.data; | |
835 | |
836 prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix: | |
837 (ngx_str_t *) &ngx_cycle->prefix; | |
838 | |
839 if (ngx_get_full_name(e->session->connection->pool, prefix, &value) | |
840 != NGX_OK) | |
841 { | |
842 e->ip = ngx_stream_script_exit; | |
843 return; | |
844 } | |
845 | |
846 e->buf = value; | |
847 | |
848 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, | |
849 "stream script fullname: \"%V\"", &value); | |
850 | |
851 e->ip += sizeof(ngx_stream_script_full_name_code_t); | |
852 } |