0001
0002
0003
0004
0005
0006
0007
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011
0012
0013 static ngx_int_t ngx_stream_script_init_arrays(
0014 ngx_stream_script_compile_t *sc);
0015 static ngx_int_t ngx_stream_script_done(ngx_stream_script_compile_t *sc);
0016 static ngx_int_t ngx_stream_script_add_copy_code(
0017 ngx_stream_script_compile_t *sc, ngx_str_t *value, ngx_uint_t last);
0018 static ngx_int_t ngx_stream_script_add_var_code(
0019 ngx_stream_script_compile_t *sc, ngx_str_t *name);
0020 #if (NGX_PCRE)
0021 static ngx_int_t ngx_stream_script_add_capture_code(
0022 ngx_stream_script_compile_t *sc, ngx_uint_t n);
0023 #endif
0024 static ngx_int_t ngx_stream_script_add_full_name_code(
0025 ngx_stream_script_compile_t *sc);
0026 static size_t ngx_stream_script_full_name_len_code(
0027 ngx_stream_script_engine_t *e);
0028 static void ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e);
0029
0030
0031 #define ngx_stream_script_exit (u_char *) &ngx_stream_script_exit_code
0032
0033 static uintptr_t ngx_stream_script_exit_code = (uintptr_t) NULL;
0034
0035
0036 void
0037 ngx_stream_script_flush_complex_value(ngx_stream_session_t *s,
0038 ngx_stream_complex_value_t *val)
0039 {
0040 ngx_uint_t *index;
0041
0042 index = val->flushes;
0043
0044 if (index) {
0045 while (*index != (ngx_uint_t) -1) {
0046
0047 if (s->variables[*index].no_cacheable) {
0048 s->variables[*index].valid = 0;
0049 s->variables[*index].not_found = 0;
0050 }
0051
0052 index++;
0053 }
0054 }
0055 }
0056
0057
0058 ngx_int_t
0059 ngx_stream_complex_value(ngx_stream_session_t *s,
0060 ngx_stream_complex_value_t *val, ngx_str_t *value)
0061 {
0062 size_t len;
0063 ngx_stream_script_code_pt code;
0064 ngx_stream_script_engine_t e;
0065 ngx_stream_script_len_code_pt lcode;
0066
0067 if (val->lengths == NULL) {
0068 *value = val->value;
0069 return NGX_OK;
0070 }
0071
0072 ngx_stream_script_flush_complex_value(s, val);
0073
0074 ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
0075
0076 e.ip = val->lengths;
0077 e.session = s;
0078 e.flushed = 1;
0079
0080 len = 0;
0081
0082 while (*(uintptr_t *) e.ip) {
0083 lcode = *(ngx_stream_script_len_code_pt *) e.ip;
0084 len += lcode(&e);
0085 }
0086
0087 value->len = len;
0088 value->data = ngx_pnalloc(s->connection->pool, len);
0089 if (value->data == NULL) {
0090 return NGX_ERROR;
0091 }
0092
0093 e.ip = val->values;
0094 e.pos = value->data;
0095 e.buf = *value;
0096
0097 while (*(uintptr_t *) e.ip) {
0098 code = *(ngx_stream_script_code_pt *) e.ip;
0099 code((ngx_stream_script_engine_t *) &e);
0100 }
0101
0102 *value = e.buf;
0103
0104 return NGX_OK;
0105 }
0106
0107
0108 ngx_int_t
0109 ngx_stream_compile_complex_value(ngx_stream_compile_complex_value_t *ccv)
0110 {
0111 ngx_str_t *v;
0112 ngx_uint_t i, n, nv, nc;
0113 ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
0114 ngx_stream_script_compile_t sc;
0115
0116 v = ccv->value;
0117
0118 nv = 0;
0119 nc = 0;
0120
0121 for (i = 0; i < v->len; i++) {
0122 if (v->data[i] == '$') {
0123 if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
0124 nc++;
0125
0126 } else {
0127 nv++;
0128 }
0129 }
0130 }
0131
0132 if ((v->len == 0 || v->data[0] != '$')
0133 && (ccv->conf_prefix || ccv->root_prefix))
0134 {
0135 if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
0136 return NGX_ERROR;
0137 }
0138
0139 ccv->conf_prefix = 0;
0140 ccv->root_prefix = 0;
0141 }
0142
0143 ccv->complex_value->value = *v;
0144 ccv->complex_value->flushes = NULL;
0145 ccv->complex_value->lengths = NULL;
0146 ccv->complex_value->values = NULL;
0147
0148 if (nv == 0 && nc == 0) {
0149 return NGX_OK;
0150 }
0151
0152 n = nv + 1;
0153
0154 if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
0155 != NGX_OK)
0156 {
0157 return NGX_ERROR;
0158 }
0159
0160 n = nv * (2 * sizeof(ngx_stream_script_copy_code_t)
0161 + sizeof(ngx_stream_script_var_code_t))
0162 + sizeof(uintptr_t);
0163
0164 if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
0165 return NGX_ERROR;
0166 }
0167
0168 n = (nv * (2 * sizeof(ngx_stream_script_copy_code_t)
0169 + sizeof(ngx_stream_script_var_code_t))
0170 + sizeof(uintptr_t)
0171 + v->len
0172 + sizeof(uintptr_t) - 1)
0173 & ~(sizeof(uintptr_t) - 1);
0174
0175 if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
0176 return NGX_ERROR;
0177 }
0178
0179 pf = &flushes;
0180 pl = &lengths;
0181 pv = &values;
0182
0183 ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t));
0184
0185 sc.cf = ccv->cf;
0186 sc.source = v;
0187 sc.flushes = &pf;
0188 sc.lengths = &pl;
0189 sc.values = &pv;
0190 sc.complete_lengths = 1;
0191 sc.complete_values = 1;
0192 sc.zero = ccv->zero;
0193 sc.conf_prefix = ccv->conf_prefix;
0194 sc.root_prefix = ccv->root_prefix;
0195
0196 if (ngx_stream_script_compile(&sc) != NGX_OK) {
0197 return NGX_ERROR;
0198 }
0199
0200 if (flushes.nelts) {
0201 ccv->complex_value->flushes = flushes.elts;
0202 ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
0203 }
0204
0205 ccv->complex_value->lengths = lengths.elts;
0206 ccv->complex_value->values = values.elts;
0207
0208 return NGX_OK;
0209 }
0210
0211
0212 char *
0213 ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
0214 void *conf)
0215 {
0216 char *p = conf;
0217
0218 ngx_str_t *value;
0219 ngx_stream_complex_value_t **cv;
0220 ngx_stream_compile_complex_value_t ccv;
0221
0222 cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
0223
0224 if (*cv != NULL) {
0225 return "is duplicate";
0226 }
0227
0228 *cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
0229 if (*cv == NULL) {
0230 return NGX_CONF_ERROR;
0231 }
0232
0233 value = cf->args->elts;
0234
0235 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
0236
0237 ccv.cf = cf;
0238 ccv.value = &value[1];
0239 ccv.complex_value = *cv;
0240
0241 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
0242 return NGX_CONF_ERROR;
0243 }
0244
0245 return NGX_CONF_OK;
0246 }
0247
0248
0249 ngx_uint_t
0250 ngx_stream_script_variables_count(ngx_str_t *value)
0251 {
0252 ngx_uint_t i, n;
0253
0254 for (n = 0, i = 0; i < value->len; i++) {
0255 if (value->data[i] == '$') {
0256 n++;
0257 }
0258 }
0259
0260 return n;
0261 }
0262
0263
0264 ngx_int_t
0265 ngx_stream_script_compile(ngx_stream_script_compile_t *sc)
0266 {
0267 u_char ch;
0268 ngx_str_t name;
0269 ngx_uint_t i, bracket;
0270
0271 if (ngx_stream_script_init_arrays(sc) != NGX_OK) {
0272 return NGX_ERROR;
0273 }
0274
0275 for (i = 0; i < sc->source->len; ) {
0276
0277 name.len = 0;
0278
0279 if (sc->source->data[i] == '$') {
0280
0281 if (++i == sc->source->len) {
0282 goto invalid_variable;
0283 }
0284
0285 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
0286 #if (NGX_PCRE)
0287 ngx_uint_t n;
0288
0289 n = sc->source->data[i] - '0';
0290
0291 if (ngx_stream_script_add_capture_code(sc, n) != NGX_OK) {
0292 return NGX_ERROR;
0293 }
0294
0295 i++;
0296
0297 continue;
0298 #else
0299 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
0300 "using variable \"$%c\" requires "
0301 "PCRE library", sc->source->data[i]);
0302 return NGX_ERROR;
0303 #endif
0304 }
0305
0306 if (sc->source->data[i] == '{') {
0307 bracket = 1;
0308
0309 if (++i == sc->source->len) {
0310 goto invalid_variable;
0311 }
0312
0313 name.data = &sc->source->data[i];
0314
0315 } else {
0316 bracket = 0;
0317 name.data = &sc->source->data[i];
0318 }
0319
0320 for ( ; i < sc->source->len; i++, name.len++) {
0321 ch = sc->source->data[i];
0322
0323 if (ch == '}' && bracket) {
0324 i++;
0325 bracket = 0;
0326 break;
0327 }
0328
0329 if ((ch >= 'A' && ch <= 'Z')
0330 || (ch >= 'a' && ch <= 'z')
0331 || (ch >= '0' && ch <= '9')
0332 || ch == '_')
0333 {
0334 continue;
0335 }
0336
0337 break;
0338 }
0339
0340 if (bracket) {
0341 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
0342 "the closing bracket in \"%V\" "
0343 "variable is missing", &name);
0344 return NGX_ERROR;
0345 }
0346
0347 if (name.len == 0) {
0348 goto invalid_variable;
0349 }
0350
0351 sc->variables++;
0352
0353 if (ngx_stream_script_add_var_code(sc, &name) != NGX_OK) {
0354 return NGX_ERROR;
0355 }
0356
0357 continue;
0358 }
0359
0360 name.data = &sc->source->data[i];
0361
0362 while (i < sc->source->len) {
0363
0364 if (sc->source->data[i] == '$') {
0365 break;
0366 }
0367
0368 i++;
0369 name.len++;
0370 }
0371
0372 sc->size += name.len;
0373
0374 if (ngx_stream_script_add_copy_code(sc, &name, (i == sc->source->len))
0375 != NGX_OK)
0376 {
0377 return NGX_ERROR;
0378 }
0379 }
0380
0381 return ngx_stream_script_done(sc);
0382
0383 invalid_variable:
0384
0385 ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
0386
0387 return NGX_ERROR;
0388 }
0389
0390
0391 u_char *
0392 ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
0393 void *code_lengths, size_t len, void *code_values)
0394 {
0395 ngx_uint_t i;
0396 ngx_stream_script_code_pt code;
0397 ngx_stream_script_engine_t e;
0398 ngx_stream_core_main_conf_t *cmcf;
0399 ngx_stream_script_len_code_pt lcode;
0400
0401 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
0402
0403 for (i = 0; i < cmcf->variables.nelts; i++) {
0404 if (s->variables[i].no_cacheable) {
0405 s->variables[i].valid = 0;
0406 s->variables[i].not_found = 0;
0407 }
0408 }
0409
0410 ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
0411
0412 e.ip = code_lengths;
0413 e.session = s;
0414 e.flushed = 1;
0415
0416 while (*(uintptr_t *) e.ip) {
0417 lcode = *(ngx_stream_script_len_code_pt *) e.ip;
0418 len += lcode(&e);
0419 }
0420
0421
0422 value->len = len;
0423 value->data = ngx_pnalloc(s->connection->pool, len);
0424 if (value->data == NULL) {
0425 return NULL;
0426 }
0427
0428 e.ip = code_values;
0429 e.pos = value->data;
0430
0431 while (*(uintptr_t *) e.ip) {
0432 code = *(ngx_stream_script_code_pt *) e.ip;
0433 code((ngx_stream_script_engine_t *) &e);
0434 }
0435
0436 return e.pos;
0437 }
0438
0439
0440 void
0441 ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s,
0442 ngx_array_t *indices)
0443 {
0444 ngx_uint_t n, *index;
0445
0446 if (indices) {
0447 index = indices->elts;
0448 for (n = 0; n < indices->nelts; n++) {
0449 if (s->variables[index[n]].no_cacheable) {
0450 s->variables[index[n]].valid = 0;
0451 s->variables[index[n]].not_found = 0;
0452 }
0453 }
0454 }
0455 }
0456
0457
0458 static ngx_int_t
0459 ngx_stream_script_init_arrays(ngx_stream_script_compile_t *sc)
0460 {
0461 ngx_uint_t n;
0462
0463 if (sc->flushes && *sc->flushes == NULL) {
0464 n = sc->variables ? sc->variables : 1;
0465 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
0466 if (*sc->flushes == NULL) {
0467 return NGX_ERROR;
0468 }
0469 }
0470
0471 if (*sc->lengths == NULL) {
0472 n = sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
0473 + sizeof(ngx_stream_script_var_code_t))
0474 + sizeof(uintptr_t);
0475
0476 *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
0477 if (*sc->lengths == NULL) {
0478 return NGX_ERROR;
0479 }
0480 }
0481
0482 if (*sc->values == NULL) {
0483 n = (sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
0484 + sizeof(ngx_stream_script_var_code_t))
0485 + sizeof(uintptr_t)
0486 + sc->source->len
0487 + sizeof(uintptr_t) - 1)
0488 & ~(sizeof(uintptr_t) - 1);
0489
0490 *sc->values = ngx_array_create(sc->cf->pool, n, 1);
0491 if (*sc->values == NULL) {
0492 return NGX_ERROR;
0493 }
0494 }
0495
0496 sc->variables = 0;
0497
0498 return NGX_OK;
0499 }
0500
0501
0502 static ngx_int_t
0503 ngx_stream_script_done(ngx_stream_script_compile_t *sc)
0504 {
0505 ngx_str_t zero;
0506 uintptr_t *code;
0507
0508 if (sc->zero) {
0509
0510 zero.len = 1;
0511 zero.data = (u_char *) "\0";
0512
0513 if (ngx_stream_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
0514 return NGX_ERROR;
0515 }
0516 }
0517
0518 if (sc->conf_prefix || sc->root_prefix) {
0519 if (ngx_stream_script_add_full_name_code(sc) != NGX_OK) {
0520 return NGX_ERROR;
0521 }
0522 }
0523
0524 if (sc->complete_lengths) {
0525 code = ngx_stream_script_add_code(*sc->lengths, sizeof(uintptr_t),
0526 NULL);
0527 if (code == NULL) {
0528 return NGX_ERROR;
0529 }
0530
0531 *code = (uintptr_t) NULL;
0532 }
0533
0534 if (sc->complete_values) {
0535 code = ngx_stream_script_add_code(*sc->values, sizeof(uintptr_t),
0536 &sc->main);
0537 if (code == NULL) {
0538 return NGX_ERROR;
0539 }
0540
0541 *code = (uintptr_t) NULL;
0542 }
0543
0544 return NGX_OK;
0545 }
0546
0547
0548 void *
0549 ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code)
0550 {
0551 u_char *elts, **p;
0552 void *new;
0553
0554 elts = codes->elts;
0555
0556 new = ngx_array_push_n(codes, size);
0557 if (new == NULL) {
0558 return NULL;
0559 }
0560
0561 if (code) {
0562 if (elts != codes->elts) {
0563 p = code;
0564 *p += (u_char *) codes->elts - elts;
0565 }
0566 }
0567
0568 return new;
0569 }
0570
0571
0572 static ngx_int_t
0573 ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc,
0574 ngx_str_t *value, ngx_uint_t last)
0575 {
0576 u_char *p;
0577 size_t size, len, zero;
0578 ngx_stream_script_copy_code_t *code;
0579
0580 zero = (sc->zero && last);
0581 len = value->len + zero;
0582
0583 code = ngx_stream_script_add_code(*sc->lengths,
0584 sizeof(ngx_stream_script_copy_code_t),
0585 NULL);
0586 if (code == NULL) {
0587 return NGX_ERROR;
0588 }
0589
0590 code->code = (ngx_stream_script_code_pt) ngx_stream_script_copy_len_code;
0591 code->len = len;
0592
0593 size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
0594 & ~(sizeof(uintptr_t) - 1);
0595
0596 code = ngx_stream_script_add_code(*sc->values, size, &sc->main);
0597 if (code == NULL) {
0598 return NGX_ERROR;
0599 }
0600
0601 code->code = ngx_stream_script_copy_code;
0602 code->len = len;
0603
0604 p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t),
0605 value->data, value->len);
0606
0607 if (zero) {
0608 *p = '\0';
0609 sc->zero = 0;
0610 }
0611
0612 return NGX_OK;
0613 }
0614
0615
0616 size_t
0617 ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e)
0618 {
0619 ngx_stream_script_copy_code_t *code;
0620
0621 code = (ngx_stream_script_copy_code_t *) e->ip;
0622
0623 e->ip += sizeof(ngx_stream_script_copy_code_t);
0624
0625 return code->len;
0626 }
0627
0628
0629 void
0630 ngx_stream_script_copy_code(ngx_stream_script_engine_t *e)
0631 {
0632 u_char *p;
0633 ngx_stream_script_copy_code_t *code;
0634
0635 code = (ngx_stream_script_copy_code_t *) e->ip;
0636
0637 p = e->pos;
0638
0639 if (!e->skip) {
0640 e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t),
0641 code->len);
0642 }
0643
0644 e->ip += sizeof(ngx_stream_script_copy_code_t)
0645 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
0646
0647 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0648 "stream script copy: \"%*s\"", e->pos - p, p);
0649 }
0650
0651
0652 static ngx_int_t
0653 ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name)
0654 {
0655 ngx_int_t index, *p;
0656 ngx_stream_script_var_code_t *code;
0657
0658 index = ngx_stream_get_variable_index(sc->cf, name);
0659
0660 if (index == NGX_ERROR) {
0661 return NGX_ERROR;
0662 }
0663
0664 if (sc->flushes) {
0665 p = ngx_array_push(*sc->flushes);
0666 if (p == NULL) {
0667 return NGX_ERROR;
0668 }
0669
0670 *p = index;
0671 }
0672
0673 code = ngx_stream_script_add_code(*sc->lengths,
0674 sizeof(ngx_stream_script_var_code_t),
0675 NULL);
0676 if (code == NULL) {
0677 return NGX_ERROR;
0678 }
0679
0680 code->code = (ngx_stream_script_code_pt)
0681 ngx_stream_script_copy_var_len_code;
0682 code->index = (uintptr_t) index;
0683
0684 code = ngx_stream_script_add_code(*sc->values,
0685 sizeof(ngx_stream_script_var_code_t),
0686 &sc->main);
0687 if (code == NULL) {
0688 return NGX_ERROR;
0689 }
0690
0691 code->code = ngx_stream_script_copy_var_code;
0692 code->index = (uintptr_t) index;
0693
0694 return NGX_OK;
0695 }
0696
0697
0698 size_t
0699 ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e)
0700 {
0701 ngx_stream_variable_value_t *value;
0702 ngx_stream_script_var_code_t *code;
0703
0704 code = (ngx_stream_script_var_code_t *) e->ip;
0705
0706 e->ip += sizeof(ngx_stream_script_var_code_t);
0707
0708 if (e->flushed) {
0709 value = ngx_stream_get_indexed_variable(e->session, code->index);
0710
0711 } else {
0712 value = ngx_stream_get_flushed_variable(e->session, code->index);
0713 }
0714
0715 if (value && !value->not_found) {
0716 return value->len;
0717 }
0718
0719 return 0;
0720 }
0721
0722
0723 void
0724 ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e)
0725 {
0726 u_char *p;
0727 ngx_stream_variable_value_t *value;
0728 ngx_stream_script_var_code_t *code;
0729
0730 code = (ngx_stream_script_var_code_t *) e->ip;
0731
0732 e->ip += sizeof(ngx_stream_script_var_code_t);
0733
0734 if (!e->skip) {
0735
0736 if (e->flushed) {
0737 value = ngx_stream_get_indexed_variable(e->session, code->index);
0738
0739 } else {
0740 value = ngx_stream_get_flushed_variable(e->session, code->index);
0741 }
0742
0743 if (value && !value->not_found) {
0744 p = e->pos;
0745 e->pos = ngx_copy(p, value->data, value->len);
0746
0747 ngx_log_debug2(NGX_LOG_DEBUG_STREAM,
0748 e->session->connection->log, 0,
0749 "stream script var: \"%*s\"", e->pos - p, p);
0750 }
0751 }
0752 }
0753
0754
0755 #if (NGX_PCRE)
0756
0757 static ngx_int_t
0758 ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc,
0759 ngx_uint_t n)
0760 {
0761 ngx_stream_script_copy_capture_code_t *code;
0762
0763 code = ngx_stream_script_add_code(*sc->lengths,
0764 sizeof(ngx_stream_script_copy_capture_code_t),
0765 NULL);
0766 if (code == NULL) {
0767 return NGX_ERROR;
0768 }
0769
0770 code->code = (ngx_stream_script_code_pt)
0771 ngx_stream_script_copy_capture_len_code;
0772 code->n = 2 * n;
0773
0774
0775 code = ngx_stream_script_add_code(*sc->values,
0776 sizeof(ngx_stream_script_copy_capture_code_t),
0777 &sc->main);
0778 if (code == NULL) {
0779 return NGX_ERROR;
0780 }
0781
0782 code->code = ngx_stream_script_copy_capture_code;
0783 code->n = 2 * n;
0784
0785 if (sc->ncaptures < n) {
0786 sc->ncaptures = n;
0787 }
0788
0789 return NGX_OK;
0790 }
0791
0792
0793 size_t
0794 ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e)
0795 {
0796 int *cap;
0797 ngx_uint_t n;
0798 ngx_stream_session_t *s;
0799 ngx_stream_script_copy_capture_code_t *code;
0800
0801 s = e->session;
0802
0803 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
0804
0805 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
0806
0807 n = code->n;
0808
0809 if (n < s->ncaptures) {
0810 cap = s->captures;
0811 return cap[n + 1] - cap[n];
0812 }
0813
0814 return 0;
0815 }
0816
0817
0818 void
0819 ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e)
0820 {
0821 int *cap;
0822 u_char *p, *pos;
0823 ngx_uint_t n;
0824 ngx_stream_session_t *s;
0825 ngx_stream_script_copy_capture_code_t *code;
0826
0827 s = e->session;
0828
0829 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
0830
0831 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
0832
0833 n = code->n;
0834
0835 pos = e->pos;
0836
0837 if (n < s->ncaptures) {
0838 cap = s->captures;
0839 p = s->captures_data;
0840 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
0841 }
0842
0843 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0844 "stream script capture: \"%*s\"", e->pos - pos, pos);
0845 }
0846
0847 #endif
0848
0849
0850 static ngx_int_t
0851 ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc)
0852 {
0853 ngx_stream_script_full_name_code_t *code;
0854
0855 code = ngx_stream_script_add_code(*sc->lengths,
0856 sizeof(ngx_stream_script_full_name_code_t),
0857 NULL);
0858 if (code == NULL) {
0859 return NGX_ERROR;
0860 }
0861
0862 code->code = (ngx_stream_script_code_pt)
0863 ngx_stream_script_full_name_len_code;
0864 code->conf_prefix = sc->conf_prefix;
0865
0866 code = ngx_stream_script_add_code(*sc->values,
0867 sizeof(ngx_stream_script_full_name_code_t), &sc->main);
0868 if (code == NULL) {
0869 return NGX_ERROR;
0870 }
0871
0872 code->code = ngx_stream_script_full_name_code;
0873 code->conf_prefix = sc->conf_prefix;
0874
0875 return NGX_OK;
0876 }
0877
0878
0879 static size_t
0880 ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e)
0881 {
0882 ngx_stream_script_full_name_code_t *code;
0883
0884 code = (ngx_stream_script_full_name_code_t *) e->ip;
0885
0886 e->ip += sizeof(ngx_stream_script_full_name_code_t);
0887
0888 return code->conf_prefix ? ngx_cycle->conf_prefix.len:
0889 ngx_cycle->prefix.len;
0890 }
0891
0892
0893 static void
0894 ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e)
0895 {
0896 ngx_stream_script_full_name_code_t *code;
0897
0898 ngx_str_t value, *prefix;
0899
0900 code = (ngx_stream_script_full_name_code_t *) e->ip;
0901
0902 value.data = e->buf.data;
0903 value.len = e->pos - e->buf.data;
0904
0905 prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
0906 (ngx_str_t *) &ngx_cycle->prefix;
0907
0908 if (ngx_get_full_name(e->session->connection->pool, prefix, &value)
0909 != NGX_OK)
0910 {
0911 e->ip = ngx_stream_script_exit;
0912 return;
0913 }
0914
0915 e->buf = value;
0916
0917 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0918 "stream script fullname: \"%V\"", &value);
0919
0920 e->ip += sizeof(ngx_stream_script_full_name_code_t);
0921 }