9
10
#include <ngx_http.h>
13
static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
14
static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
15
static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
16
ngx_str_t *value, ngx_uint_t last);
17
static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
19
static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
21
static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
25
ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
26
static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
27
static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
12
30
#define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
14
32
static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
36
ngx_http_script_flush_complex_value(ngx_http_request_t *r,
37
ngx_http_complex_value_t *val)
44
while (*index != (ngx_uint_t) -1) {
46
if (r->variables[*index].no_cacheable) {
47
r->variables[*index].valid = 0;
48
r->variables[*index].not_found = 0;
58
ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
62
ngx_http_script_code_pt code;
63
ngx_http_script_len_code_pt lcode;
64
ngx_http_script_engine_t e;
66
if (val->lengths == NULL) {
71
ngx_http_script_flush_complex_value(r, val);
73
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
81
while (*(uintptr_t *) e.ip) {
82
lcode = *(ngx_http_script_len_code_pt *) e.ip;
87
value->data = ngx_pnalloc(r->pool, len);
88
if (value->data == NULL) {
96
while (*(uintptr_t *) e.ip) {
97
code = *(ngx_http_script_code_pt *) e.ip;
98
code((ngx_http_script_engine_t *) &e);
108
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
111
ngx_uint_t i, n, nv, nc;
112
ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
113
ngx_http_script_compile_t sc;
120
for (i = 0; i < v->len; i++) {
121
if (v->data[i] == '$') {
122
if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
131
if ((v->len == 0 || v->data[0] != '$')
132
&& (ccv->conf_prefix || ccv->root_prefix))
134
if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
138
ccv->conf_prefix = 0;
139
ccv->root_prefix = 0;
142
ccv->complex_value->value = *v;
143
ccv->complex_value->flushes = NULL;
144
ccv->complex_value->lengths = NULL;
145
ccv->complex_value->values = NULL;
147
if (nv == 0 && nc == 0) {
153
if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
159
n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
160
+ sizeof(ngx_http_script_var_code_t))
163
if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
167
n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
168
+ sizeof(ngx_http_script_var_code_t))
171
+ sizeof(uintptr_t) - 1)
172
& ~(sizeof(uintptr_t) - 1);
174
if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
182
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
189
sc.complete_lengths = 1;
190
sc.complete_values = 1;
192
sc.conf_prefix = ccv->conf_prefix;
193
sc.root_prefix = ccv->root_prefix;
195
if (ngx_http_script_compile(&sc) != NGX_OK) {
200
ccv->complex_value->flushes = flushes.elts;
201
ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
204
ccv->complex_value->lengths = lengths.elts;
205
ccv->complex_value->values = values.elts;
212
ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
217
ngx_http_complex_value_t **cv;
218
ngx_http_compile_complex_value_t ccv;
220
cv = (ngx_http_complex_value_t **) (p + cmd->offset);
226
*cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
228
return NGX_CONF_ERROR;
231
value = cf->args->elts;
233
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
236
ccv.value = &value[1];
237
ccv.complex_value = *cv;
239
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
240
return NGX_CONF_ERROR;
248
ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
252
ngx_http_complex_value_t *cv;
254
if (predicates == NULL) {
258
cv = predicates->elts;
260
for (i = 0; i < predicates->nelts; i++) {
261
if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
265
if (val.len && (val.len != 1 || val.data[0] != '0')) {
275
ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
282
ngx_http_complex_value_t *cv;
283
ngx_http_compile_complex_value_t ccv;
285
a = (ngx_array_t **) (p + cmd->offset);
287
if (*a == NGX_CONF_UNSET_PTR) {
288
*a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t));
290
return NGX_CONF_ERROR;
294
value = cf->args->elts;
296
for (i = 1; i < cf->args->nelts; i++) {
297
cv = ngx_array_push(*a);
299
return NGX_CONF_ERROR;
302
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
305
ccv.value = &value[i];
306
ccv.complex_value = cv;
308
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
309
return NGX_CONF_ERROR;
18
318
ngx_http_script_variables_count(ngx_str_t *value)
33
333
ngx_http_script_compile(ngx_http_script_compile_t *sc)
40
ngx_uint_t i, n, bracket;
41
ngx_http_script_var_code_t *var_code;
42
ngx_http_script_copy_code_t *copy;
43
ngx_http_script_copy_capture_code_t *copy_capture;
45
if (sc->flushes && *sc->flushes == NULL) {
46
n = sc->variables ? sc->variables : 1;
47
*sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
48
if (*sc->flushes == NULL) {
54
if (*sc->lengths == NULL) {
55
n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
56
+ sizeof(ngx_http_script_var_code_t))
59
*sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
60
if (*sc->lengths == NULL) {
66
if (*sc->values == NULL) {
67
n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
68
+ sizeof(ngx_http_script_var_code_t))
71
+ sizeof(uintptr_t) - 1)
72
& ~(sizeof(uintptr_t) - 1);
74
*sc->values = ngx_array_create(sc->cf->pool, n, 1);
75
if (*sc->values == NULL) {
337
ngx_uint_t i, bracket;
339
if (ngx_http_script_init_arrays(sc) != NGX_OK) {
82
343
for (i = 0; i < sc->source->len; /* void */ ) {
245
445
name.data = &sc->source->data[i];
247
while (i < sc->source->len
248
&& sc->source->data[i] != '$'
249
&& !(sc->source->data[i] == '?' && sc->compile_args))
447
while (i < sc->source->len) {
449
if (sc->source->data[i] == '$') {
453
if (sc->source->data[i] == '?') {
457
if (sc->compile_args) {
255
466
sc->size += name.len;
257
copy = ngx_http_script_add_code(*sc->lengths,
258
sizeof(ngx_http_script_copy_code_t),
264
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
265
copy->len = name.len;
267
size = (sizeof(ngx_http_script_copy_code_t) + name.len
268
+ sizeof(uintptr_t) - 1)
269
& ~(sizeof(uintptr_t) - 1);
271
copy = ngx_http_script_add_code(*sc->values, size, &sc->main);
276
copy->code = ngx_http_script_copy_code;
277
copy->len = name.len;
279
ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t),
280
name.data, name.len);
283
if (sc->complete_lengths) {
284
code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
289
*code = (uintptr_t) NULL;
292
if (sc->complete_values) {
293
code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
299
*code = (uintptr_t) NULL;
468
if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
475
return ngx_http_script_done(sc);
304
477
invalid_variable:
553
ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
557
if (sc->flushes && *sc->flushes == NULL) {
558
n = sc->variables ? sc->variables : 1;
559
*sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
560
if (*sc->flushes == NULL) {
565
if (*sc->lengths == NULL) {
566
n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
567
+ sizeof(ngx_http_script_var_code_t))
570
*sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
571
if (*sc->lengths == NULL) {
576
if (*sc->values == NULL) {
577
n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
578
+ sizeof(ngx_http_script_var_code_t))
581
+ sizeof(uintptr_t) - 1)
582
& ~(sizeof(uintptr_t) - 1);
584
*sc->values = ngx_array_create(sc->cf->pool, n, 1);
585
if (*sc->values == NULL) {
597
ngx_http_script_done(ngx_http_script_compile_t *sc)
605
zero.data = (u_char *) "\0";
607
if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
612
if (sc->conf_prefix || sc->root_prefix) {
613
if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
618
if (sc->complete_lengths) {
619
code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
624
*code = (uintptr_t) NULL;
627
if (sc->complete_values) {
628
code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
634
*code = (uintptr_t) NULL;
380
642
ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
431
736
ngx_http_script_copy_code(ngx_http_script_engine_t *e)
433
739
ngx_http_script_copy_code_t *code;
435
741
code = (ngx_http_script_copy_code_t *) e->ip;
438
e->pos = ngx_copy(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t),
746
e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_script_copy_code_t),
442
750
e->ip += sizeof(ngx_http_script_copy_code_t)
443
751
+ ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
445
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
446
"http script copy: \"%V\"", &e->buf);
753
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
754
"http script copy: \"%*s\"", e->pos - p, p);
759
ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name)
762
ngx_http_script_var_code_t *code;
764
index = ngx_http_get_variable_index(sc->cf, name);
766
if (index == NGX_ERROR) {
771
p = ngx_array_push(*sc->flushes);
779
code = ngx_http_script_add_code(*sc->lengths,
780
sizeof(ngx_http_script_var_code_t), NULL);
785
code->code = (ngx_http_script_code_pt) ngx_http_script_copy_var_len_code;
786
code->index = (uintptr_t) index;
788
code = ngx_http_script_add_code(*sc->values,
789
sizeof(ngx_http_script_var_code_t),
795
code->code = ngx_http_script_copy_var_code;
796
code->index = (uintptr_t) index;
494
847
if (value && !value->not_found) {
495
e->pos = ngx_copy(e->pos, value->data, value->len);
849
e->pos = ngx_copy(p, value->data, value->len);
497
ngx_log_debug1(NGX_LOG_DEBUG_HTTP,
851
ngx_log_debug2(NGX_LOG_DEBUG_HTTP,
498
852
e->request->connection->log, 0,
499
"http script var: \"%V\"", &e->buf);
506
ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
508
ngx_http_script_copy_capture_code_t *code;
510
code = (ngx_http_script_copy_capture_code_t *) e->ip;
512
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
514
if (code->n < e->ncaptures) {
515
if ((e->is_args || e->quote)
516
&& (e->request->quoted_uri || e->request->plus_in_uri))
518
return e->captures[code->n + 1] - e->captures[code->n]
519
+ 2 * ngx_escape_uri(NULL,
520
&e->line.data[e->captures[code->n]],
521
e->captures[code->n + 1] - e->captures[code->n],
524
return e->captures[code->n + 1] - e->captures[code->n];
533
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
535
ngx_http_script_copy_capture_code_t *code;
537
code = (ngx_http_script_copy_capture_code_t *) e->ip;
539
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
541
if (code->n < e->ncaptures) {
542
if ((e->is_args || e->quote)
543
&& (e->request->quoted_uri || e->request->plus_in_uri))
545
e->pos = (u_char *) ngx_escape_uri(e->pos,
546
&e->line.data[e->captures[code->n]],
547
e->captures[code->n + 1] - e->captures[code->n],
550
e->pos = ngx_copy(e->pos,
551
&e->line.data[e->captures[code->n]],
552
e->captures[code->n + 1] - e->captures[code->n]);
556
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
557
"http script capture: \"%V\"", &e->buf);
853
"http script var: \"%*s\"", e->pos - p, p);
860
ngx_http_script_add_args_code(ngx_http_script_compile_t *sc)
864
code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
869
*code = (uintptr_t) ngx_http_script_mark_args_code;
871
code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main);
876
*code = (uintptr_t) ngx_http_script_start_args_code;
847
if (ngx_http_set_exten(r) != NGX_OK) {
848
e->ip = ngx_http_script_exit;
849
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1160
ngx_http_set_exten(r);
854
1163
e->ip += sizeof(ngx_http_script_regex_end_code_t);
1168
ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
1170
ngx_http_script_copy_capture_code_t *code;
1172
code = ngx_http_script_add_code(*sc->lengths,
1173
sizeof(ngx_http_script_copy_capture_code_t),
1179
code->code = (ngx_http_script_code_pt)
1180
ngx_http_script_copy_capture_len_code;
1184
code = ngx_http_script_add_code(*sc->values,
1185
sizeof(ngx_http_script_copy_capture_code_t),
1191
code->code = ngx_http_script_copy_capture_code;
1194
if (sc->ncaptures < n) {
1203
ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
1208
ngx_http_request_t *r;
1209
ngx_http_script_copy_capture_code_t *code;
1213
code = (ngx_http_script_copy_capture_code_t *) e->ip;
1215
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
1219
if (n < r->ncaptures) {
1223
if ((e->is_args || e->quote)
1224
&& (e->request->quoted_uri || e->request->plus_in_uri))
1226
p = r->captures_data;
1228
return cap[n + 1] - cap[n]
1229
+ 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n],
1232
return cap[n + 1] - cap[n];
1241
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
1246
ngx_http_request_t *r;
1247
ngx_http_script_copy_capture_code_t *code;
1251
code = (ngx_http_script_copy_capture_code_t *) e->ip;
1253
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
1259
if (n < r->ncaptures) {
1262
p = r->captures_data;
1264
if ((e->is_args || e->quote)
1265
&& (e->request->quoted_uri || e->request->plus_in_uri))
1267
e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
1268
cap[n + 1] - cap[n],
1271
e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
1275
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1276
"http script capture: \"%*s\"", e->pos - pos, pos);
1283
ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
1285
ngx_http_script_full_name_code_t *code;
1287
code = ngx_http_script_add_code(*sc->lengths,
1288
sizeof(ngx_http_script_full_name_code_t),
1294
code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
1295
code->conf_prefix = sc->conf_prefix;
1297
code = ngx_http_script_add_code(*sc->values,
1298
sizeof(ngx_http_script_full_name_code_t),
1304
code->code = ngx_http_script_full_name_code;
1305
code->conf_prefix = sc->conf_prefix;
1312
ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
1314
ngx_http_script_full_name_code_t *code;
1316
code = (ngx_http_script_full_name_code_t *) e->ip;
1318
e->ip += sizeof(ngx_http_script_full_name_code_t);
1320
return code->conf_prefix ? ngx_cycle->conf_prefix.len:
1321
ngx_cycle->prefix.len;
1326
ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
1328
ngx_http_script_full_name_code_t *code;
1332
code = (ngx_http_script_full_name_code_t *) e->ip;
1334
value.data = e->buf.data;
1335
value.len = e->pos - e->buf.data;
1337
if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
1340
e->ip = ngx_http_script_exit;
1341
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1347
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1348
"http script fullname: \"%V\"", &value);
1350
e->ip += sizeof(ngx_http_script_full_name_code_t);
861
1355
ngx_http_script_return_code(ngx_http_script_engine_t *e)
995
1492
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1494
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
1496
of.read_ahead = clcf->read_ahead;
1497
of.directio = clcf->directio;
998
1498
of.valid = clcf->open_file_cache_valid;
999
1499
of.min_uses = clcf->open_file_cache_min_uses;
1000
1501
of.errors = clcf->open_file_cache_errors;
1001
1502
of.events = clcf->open_file_cache_events;
1504
if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
1505
e->ip = ngx_http_script_exit;
1506
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1003
1510
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
1006
if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
1513
if (of.err != NGX_ENOENT
1514
&& of.err != NGX_ENOTDIR
1515
&& of.err != NGX_ENAMETOOLONG)
1007
1517
ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
1008
ngx_file_info_n " \"%s\" failed", value->data);
1518
"%s \"%s\" failed", of.failed, value->data);
1011
1521
switch (code->op) {
1014
1524
case ngx_http_script_file_dir:
1015
1525
case ngx_http_script_file_exists:
1016
1526
case ngx_http_script_file_exec:
1019
1529
case ngx_http_script_file_not_plain:
1020
1530
case ngx_http_script_file_not_dir:
1021
1531
case ngx_http_script_file_not_exists:
1022
1532
case ngx_http_script_file_not_exec:
1029
1539
switch (code->op) {
1030
1540
case ngx_http_script_file_plain:
1031
1541
if (of.is_file) {
1036
1546
case ngx_http_script_file_not_plain:
1037
1547
if (of.is_file) {
1042
1552
case ngx_http_script_file_dir:
1043
1553
if (of.is_dir) {
1048
1558
case ngx_http_script_file_not_dir:
1049
1559
if (of.is_dir) {
1054
1564
case ngx_http_script_file_exists:
1055
1565
if (of.is_file || of.is_dir || of.is_link) {
1060
1570
case ngx_http_script_file_not_exists:
1061
1571
if (of.is_file || of.is_dir || of.is_link) {
1066
1576
case ngx_http_script_file_exec:
1067
1577
if (of.is_exec) {
1072
1582
case ngx_http_script_file_not_exec:
1073
1583
if (of.is_exec) {
1081
1591
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1082
1592
"http script file op false");