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) (void *)
0591 ngx_stream_script_copy_len_code;
0592 code->len = len;
0593
0594 size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
0595 & ~(sizeof(uintptr_t) - 1);
0596
0597 code = ngx_stream_script_add_code(*sc->values, size, &sc->main);
0598 if (code == NULL) {
0599 return NGX_ERROR;
0600 }
0601
0602 code->code = ngx_stream_script_copy_code;
0603 code->len = len;
0604
0605 p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t),
0606 value->data, value->len);
0607
0608 if (zero) {
0609 *p = '\0';
0610 sc->zero = 0;
0611 }
0612
0613 return NGX_OK;
0614 }
0615
0616
0617 size_t
0618 ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e)
0619 {
0620 ngx_stream_script_copy_code_t *code;
0621
0622 code = (ngx_stream_script_copy_code_t *) e->ip;
0623
0624 e->ip += sizeof(ngx_stream_script_copy_code_t);
0625
0626 return code->len;
0627 }
0628
0629
0630 void
0631 ngx_stream_script_copy_code(ngx_stream_script_engine_t *e)
0632 {
0633 u_char *p;
0634 ngx_stream_script_copy_code_t *code;
0635
0636 code = (ngx_stream_script_copy_code_t *) e->ip;
0637
0638 p = e->pos;
0639
0640 if (!e->skip) {
0641 e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t),
0642 code->len);
0643 }
0644
0645 e->ip += sizeof(ngx_stream_script_copy_code_t)
0646 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
0647
0648 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0649 "stream script copy: \"%*s\"", e->pos - p, p);
0650 }
0651
0652
0653 static ngx_int_t
0654 ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name)
0655 {
0656 ngx_int_t index, *p;
0657 ngx_stream_script_var_code_t *code;
0658
0659 index = ngx_stream_get_variable_index(sc->cf, name);
0660
0661 if (index == NGX_ERROR) {
0662 return NGX_ERROR;
0663 }
0664
0665 if (sc->flushes) {
0666 p = ngx_array_push(*sc->flushes);
0667 if (p == NULL) {
0668 return NGX_ERROR;
0669 }
0670
0671 *p = index;
0672 }
0673
0674 code = ngx_stream_script_add_code(*sc->lengths,
0675 sizeof(ngx_stream_script_var_code_t),
0676 NULL);
0677 if (code == NULL) {
0678 return NGX_ERROR;
0679 }
0680
0681 code->code = (ngx_stream_script_code_pt) (void *)
0682 ngx_stream_script_copy_var_len_code;
0683 code->index = (uintptr_t) index;
0684
0685 code = ngx_stream_script_add_code(*sc->values,
0686 sizeof(ngx_stream_script_var_code_t),
0687 &sc->main);
0688 if (code == NULL) {
0689 return NGX_ERROR;
0690 }
0691
0692 code->code = ngx_stream_script_copy_var_code;
0693 code->index = (uintptr_t) index;
0694
0695 return NGX_OK;
0696 }
0697
0698
0699 size_t
0700 ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e)
0701 {
0702 ngx_stream_variable_value_t *value;
0703 ngx_stream_script_var_code_t *code;
0704
0705 code = (ngx_stream_script_var_code_t *) e->ip;
0706
0707 e->ip += sizeof(ngx_stream_script_var_code_t);
0708
0709 if (e->flushed) {
0710 value = ngx_stream_get_indexed_variable(e->session, code->index);
0711
0712 } else {
0713 value = ngx_stream_get_flushed_variable(e->session, code->index);
0714 }
0715
0716 if (value && !value->not_found) {
0717 return value->len;
0718 }
0719
0720 return 0;
0721 }
0722
0723
0724 void
0725 ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e)
0726 {
0727 u_char *p;
0728 ngx_stream_variable_value_t *value;
0729 ngx_stream_script_var_code_t *code;
0730
0731 code = (ngx_stream_script_var_code_t *) e->ip;
0732
0733 e->ip += sizeof(ngx_stream_script_var_code_t);
0734
0735 if (!e->skip) {
0736
0737 if (e->flushed) {
0738 value = ngx_stream_get_indexed_variable(e->session, code->index);
0739
0740 } else {
0741 value = ngx_stream_get_flushed_variable(e->session, code->index);
0742 }
0743
0744 if (value && !value->not_found) {
0745 p = e->pos;
0746 e->pos = ngx_copy(p, value->data, value->len);
0747
0748 ngx_log_debug2(NGX_LOG_DEBUG_STREAM,
0749 e->session->connection->log, 0,
0750 "stream script var: \"%*s\"", e->pos - p, p);
0751 }
0752 }
0753 }
0754
0755
0756 #if (NGX_PCRE)
0757
0758 static ngx_int_t
0759 ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc,
0760 ngx_uint_t n)
0761 {
0762 ngx_stream_script_copy_capture_code_t *code;
0763
0764 code = ngx_stream_script_add_code(*sc->lengths,
0765 sizeof(ngx_stream_script_copy_capture_code_t),
0766 NULL);
0767 if (code == NULL) {
0768 return NGX_ERROR;
0769 }
0770
0771 code->code = (ngx_stream_script_code_pt) (void *)
0772 ngx_stream_script_copy_capture_len_code;
0773 code->n = 2 * n;
0774
0775
0776 code = ngx_stream_script_add_code(*sc->values,
0777 sizeof(ngx_stream_script_copy_capture_code_t),
0778 &sc->main);
0779 if (code == NULL) {
0780 return NGX_ERROR;
0781 }
0782
0783 code->code = ngx_stream_script_copy_capture_code;
0784 code->n = 2 * n;
0785
0786 if (sc->ncaptures < n) {
0787 sc->ncaptures = n;
0788 }
0789
0790 return NGX_OK;
0791 }
0792
0793
0794 size_t
0795 ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e)
0796 {
0797 int *cap;
0798 ngx_uint_t n;
0799 ngx_stream_session_t *s;
0800 ngx_stream_script_copy_capture_code_t *code;
0801
0802 s = e->session;
0803
0804 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
0805
0806 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
0807
0808 n = code->n;
0809
0810 if (n < s->ncaptures) {
0811 cap = s->captures;
0812 return cap[n + 1] - cap[n];
0813 }
0814
0815 return 0;
0816 }
0817
0818
0819 void
0820 ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e)
0821 {
0822 int *cap;
0823 u_char *p, *pos;
0824 ngx_uint_t n;
0825 ngx_stream_session_t *s;
0826 ngx_stream_script_copy_capture_code_t *code;
0827
0828 s = e->session;
0829
0830 code = (ngx_stream_script_copy_capture_code_t *) e->ip;
0831
0832 e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
0833
0834 n = code->n;
0835
0836 pos = e->pos;
0837
0838 if (n < s->ncaptures) {
0839 cap = s->captures;
0840 p = s->captures_data;
0841 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
0842 }
0843
0844 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0845 "stream script capture: \"%*s\"", e->pos - pos, pos);
0846 }
0847
0848 #endif
0849
0850
0851 static ngx_int_t
0852 ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc)
0853 {
0854 ngx_stream_script_full_name_code_t *code;
0855
0856 code = ngx_stream_script_add_code(*sc->lengths,
0857 sizeof(ngx_stream_script_full_name_code_t),
0858 NULL);
0859 if (code == NULL) {
0860 return NGX_ERROR;
0861 }
0862
0863 code->code = (ngx_stream_script_code_pt) (void *)
0864 ngx_stream_script_full_name_len_code;
0865 code->conf_prefix = sc->conf_prefix;
0866
0867 code = ngx_stream_script_add_code(*sc->values,
0868 sizeof(ngx_stream_script_full_name_code_t), &sc->main);
0869 if (code == NULL) {
0870 return NGX_ERROR;
0871 }
0872
0873 code->code = ngx_stream_script_full_name_code;
0874 code->conf_prefix = sc->conf_prefix;
0875
0876 return NGX_OK;
0877 }
0878
0879
0880 static size_t
0881 ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e)
0882 {
0883 ngx_stream_script_full_name_code_t *code;
0884
0885 code = (ngx_stream_script_full_name_code_t *) e->ip;
0886
0887 e->ip += sizeof(ngx_stream_script_full_name_code_t);
0888
0889 return code->conf_prefix ? ngx_cycle->conf_prefix.len:
0890 ngx_cycle->prefix.len;
0891 }
0892
0893
0894 static void
0895 ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e)
0896 {
0897 ngx_stream_script_full_name_code_t *code;
0898
0899 ngx_str_t value, *prefix;
0900
0901 code = (ngx_stream_script_full_name_code_t *) e->ip;
0902
0903 value.data = e->buf.data;
0904 value.len = e->pos - e->buf.data;
0905
0906 prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
0907 (ngx_str_t *) &ngx_cycle->prefix;
0908
0909 if (ngx_get_full_name(e->session->connection->pool, prefix, &value)
0910 != NGX_OK)
0911 {
0912 e->ip = ngx_stream_script_exit;
0913 return;
0914 }
0915
0916 e->buf = value;
0917
0918 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
0919 "stream script fullname: \"%V\"", &value);
0920
0921 e->ip += sizeof(ngx_stream_script_full_name_code_t);
0922 }