~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/http/ngx_http_script.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
9
10
#include <ngx_http.h>
10
11
 
11
12
 
 
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,
 
18
    ngx_str_t *name);
 
19
static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
 
20
#if (NGX_PCRE)
 
21
static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
 
22
     ngx_uint_t n);
 
23
#endif
 
24
static ngx_int_t
 
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);
 
28
 
 
29
 
12
30
#define ngx_http_script_exit  (u_char *) &ngx_http_script_exit_code
13
31
 
14
32
static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
15
33
 
16
34
 
 
35
void
 
36
ngx_http_script_flush_complex_value(ngx_http_request_t *r,
 
37
    ngx_http_complex_value_t *val)
 
38
{
 
39
    ngx_uint_t *index;
 
40
 
 
41
    index = val->flushes;
 
42
 
 
43
    if (index) {
 
44
        while (*index != (ngx_uint_t) -1) {
 
45
 
 
46
            if (r->variables[*index].no_cacheable) {
 
47
                r->variables[*index].valid = 0;
 
48
                r->variables[*index].not_found = 0;
 
49
            }
 
50
 
 
51
            index++;
 
52
        }
 
53
    }
 
54
}
 
55
 
 
56
 
 
57
ngx_int_t
 
58
ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
 
59
    ngx_str_t *value)
 
60
{
 
61
    size_t                        len;
 
62
    ngx_http_script_code_pt       code;
 
63
    ngx_http_script_len_code_pt   lcode;
 
64
    ngx_http_script_engine_t      e;
 
65
 
 
66
    if (val->lengths == NULL) {
 
67
        *value = val->value;
 
68
        return NGX_OK;
 
69
    }
 
70
 
 
71
    ngx_http_script_flush_complex_value(r, val);
 
72
 
 
73
    ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
 
74
 
 
75
    e.ip = val->lengths;
 
76
    e.request = r;
 
77
    e.flushed = 1;
 
78
 
 
79
    len = 0;
 
80
 
 
81
    while (*(uintptr_t *) e.ip) {
 
82
        lcode = *(ngx_http_script_len_code_pt *) e.ip;
 
83
        len += lcode(&e);
 
84
    }
 
85
 
 
86
    value->len = len;
 
87
    value->data = ngx_pnalloc(r->pool, len);
 
88
    if (value->data == NULL) {
 
89
        return NGX_ERROR;
 
90
    }
 
91
 
 
92
    e.ip = val->values;
 
93
    e.pos = value->data;
 
94
    e.buf = *value;
 
95
 
 
96
    while (*(uintptr_t *) e.ip) {
 
97
        code = *(ngx_http_script_code_pt *) e.ip;
 
98
        code((ngx_http_script_engine_t *) &e);
 
99
    }
 
100
 
 
101
    *value = e.buf;
 
102
 
 
103
    return NGX_OK;
 
104
}
 
105
 
 
106
 
 
107
ngx_int_t
 
108
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
 
109
{
 
110
    ngx_str_t                  *v;
 
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;
 
114
 
 
115
    v = ccv->value;
 
116
 
 
117
    nv = 0;
 
118
    nc = 0;
 
119
 
 
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') {
 
123
                nc++;
 
124
 
 
125
            } else {
 
126
                nv++;
 
127
            }
 
128
        }
 
129
    }
 
130
 
 
131
    if ((v->len == 0 || v->data[0] != '$')
 
132
        && (ccv->conf_prefix || ccv->root_prefix))
 
133
    {
 
134
        if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
 
135
            return NGX_ERROR;
 
136
        }
 
137
 
 
138
        ccv->conf_prefix = 0;
 
139
        ccv->root_prefix = 0;
 
140
    }
 
141
 
 
142
    ccv->complex_value->value = *v;
 
143
    ccv->complex_value->flushes = NULL;
 
144
    ccv->complex_value->lengths = NULL;
 
145
    ccv->complex_value->values = NULL;
 
146
 
 
147
    if (nv == 0 && nc == 0) {
 
148
        return NGX_OK;
 
149
    }
 
150
 
 
151
    n = nv + 1;
 
152
 
 
153
    if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
 
154
        != NGX_OK)
 
155
    {
 
156
        return NGX_ERROR;
 
157
    }
 
158
 
 
159
    n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
 
160
                  + sizeof(ngx_http_script_var_code_t))
 
161
        + sizeof(uintptr_t);
 
162
 
 
163
    if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
 
164
        return NGX_ERROR;
 
165
    }
 
166
 
 
167
    n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
 
168
                   + sizeof(ngx_http_script_var_code_t))
 
169
                + sizeof(uintptr_t)
 
170
                + v->len
 
171
                + sizeof(uintptr_t) - 1)
 
172
            & ~(sizeof(uintptr_t) - 1);
 
173
 
 
174
    if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
 
175
        return NGX_ERROR;
 
176
    }
 
177
 
 
178
    pf = &flushes;
 
179
    pl = &lengths;
 
180
    pv = &values;
 
181
 
 
182
    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
 
183
 
 
184
    sc.cf = ccv->cf;
 
185
    sc.source = v;
 
186
    sc.flushes = &pf;
 
187
    sc.lengths = &pl;
 
188
    sc.values = &pv;
 
189
    sc.complete_lengths = 1;
 
190
    sc.complete_values = 1;
 
191
    sc.zero = ccv->zero;
 
192
    sc.conf_prefix = ccv->conf_prefix;
 
193
    sc.root_prefix = ccv->root_prefix;
 
194
 
 
195
    if (ngx_http_script_compile(&sc) != NGX_OK) {
 
196
        return NGX_ERROR;
 
197
    }
 
198
 
 
199
    if (flushes.nelts) {
 
200
        ccv->complex_value->flushes = flushes.elts;
 
201
        ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
 
202
    }
 
203
 
 
204
    ccv->complex_value->lengths = lengths.elts;
 
205
    ccv->complex_value->values = values.elts;
 
206
 
 
207
    return NGX_OK;
 
208
}
 
209
 
 
210
 
 
211
char *
 
212
ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
213
{
 
214
    char  *p = conf;
 
215
 
 
216
    ngx_str_t                          *value;
 
217
    ngx_http_complex_value_t          **cv;
 
218
    ngx_http_compile_complex_value_t    ccv;
 
219
 
 
220
    cv = (ngx_http_complex_value_t **) (p + cmd->offset);
 
221
 
 
222
    if (*cv != NULL) {
 
223
        return "duplicate";
 
224
    }
 
225
 
 
226
    *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
 
227
    if (*cv == NULL) {
 
228
        return NGX_CONF_ERROR;
 
229
    }
 
230
 
 
231
    value = cf->args->elts;
 
232
 
 
233
    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
 
234
 
 
235
    ccv.cf = cf;
 
236
    ccv.value = &value[1];
 
237
    ccv.complex_value = *cv;
 
238
 
 
239
    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
 
240
        return NGX_CONF_ERROR;
 
241
    }
 
242
 
 
243
    return NGX_CONF_OK;
 
244
}
 
245
 
 
246
 
 
247
ngx_int_t
 
248
ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
 
249
{
 
250
    ngx_str_t                  val;
 
251
    ngx_uint_t                 i;
 
252
    ngx_http_complex_value_t  *cv;
 
253
 
 
254
    if (predicates == NULL) {
 
255
        return NGX_OK;
 
256
    }
 
257
 
 
258
    cv = predicates->elts;
 
259
 
 
260
    for (i = 0; i < predicates->nelts; i++) {
 
261
        if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
 
262
            return NGX_ERROR;
 
263
        }
 
264
 
 
265
        if (val.len && (val.len != 1 || val.data[0] != '0')) {
 
266
            return NGX_DECLINED;
 
267
        }
 
268
    }
 
269
 
 
270
    return NGX_OK;
 
271
}
 
272
 
 
273
 
 
274
char *
 
275
ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
276
{
 
277
    char  *p = conf;
 
278
 
 
279
    ngx_str_t                          *value;
 
280
    ngx_uint_t                          i;
 
281
    ngx_array_t                       **a;
 
282
    ngx_http_complex_value_t           *cv;
 
283
    ngx_http_compile_complex_value_t    ccv;
 
284
 
 
285
    a = (ngx_array_t **) (p + cmd->offset);
 
286
 
 
287
    if (*a == NGX_CONF_UNSET_PTR) {
 
288
        *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t));
 
289
        if (*a == NULL) {
 
290
            return NGX_CONF_ERROR;
 
291
        }
 
292
    }
 
293
 
 
294
    value = cf->args->elts;
 
295
 
 
296
    for (i = 1; i < cf->args->nelts; i++) {
 
297
        cv = ngx_array_push(*a);
 
298
        if (cv == NULL) {
 
299
            return NGX_CONF_ERROR;
 
300
        }
 
301
 
 
302
        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
 
303
 
 
304
        ccv.cf = cf;
 
305
        ccv.value = &value[i];
 
306
        ccv.complex_value = cv;
 
307
 
 
308
        if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
 
309
            return NGX_CONF_ERROR;
 
310
        }
 
311
    }
 
312
 
 
313
    return NGX_CONF_OK;
 
314
}
 
315
 
 
316
 
17
317
ngx_uint_t
18
318
ngx_http_script_variables_count(ngx_str_t *value)
19
319
{
32
332
ngx_int_t
33
333
ngx_http_script_compile(ngx_http_script_compile_t *sc)
34
334
{
35
 
    u_char                                ch;
36
 
    size_t                                size;
37
 
    ngx_int_t                             index, *p;
38
 
    ngx_str_t                             name;
39
 
    uintptr_t                            *code;
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;
44
 
 
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) {
49
 
            return NGX_ERROR;
50
 
        }
51
 
    }
52
 
 
53
 
 
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))
57
 
            + sizeof(uintptr_t);
58
 
 
59
 
        *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
60
 
        if (*sc->lengths == NULL) {
61
 
            return NGX_ERROR;
62
 
        }
63
 
    }
64
 
 
65
 
 
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))
69
 
                + sizeof(uintptr_t)
70
 
                + sc->source->len
71
 
                + sizeof(uintptr_t) - 1)
72
 
            & ~(sizeof(uintptr_t) - 1);
73
 
 
74
 
        *sc->values = ngx_array_create(sc->cf->pool, n, 1);
75
 
        if (*sc->values == NULL) {
76
 
            return NGX_ERROR;
77
 
        }
78
 
    }
79
 
 
80
 
    sc->variables = 0;
 
335
    u_char       ch;
 
336
    ngx_str_t    name;
 
337
    ngx_uint_t   i, bracket;
 
338
 
 
339
    if (ngx_http_script_init_arrays(sc) != NGX_OK) {
 
340
        return NGX_ERROR;
 
341
    }
81
342
 
82
343
    for (i = 0; i < sc->source->len; /* void */ ) {
83
344
 
89
350
                goto invalid_variable;
90
351
            }
91
352
 
 
353
#if (NGX_PCRE)
 
354
            {
 
355
            ngx_uint_t  n;
 
356
 
92
357
            if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
93
358
 
94
359
                n = sc->source->data[i] - '0';
99
364
 
100
365
                sc->captures_mask |= 1 << n;
101
366
 
102
 
                copy_capture = ngx_http_script_add_code(*sc->lengths,
103
 
                                   sizeof(ngx_http_script_copy_capture_code_t),
104
 
                                   NULL);
105
 
                if (copy_capture == NULL) {
106
 
                    return NGX_ERROR;
107
 
                }
108
 
 
109
 
                copy_capture->code = (ngx_http_script_code_pt)
110
 
                                         ngx_http_script_copy_capture_len_code;
111
 
                copy_capture->n = 2 * n;
112
 
 
113
 
 
114
 
                copy_capture = ngx_http_script_add_code(*sc->values,
115
 
                                   sizeof(ngx_http_script_copy_capture_code_t),
116
 
                                   &sc->main);
117
 
                if (copy_capture == NULL) {
118
 
                    return NGX_ERROR;
119
 
                }
120
 
 
121
 
                copy_capture->code = ngx_http_script_copy_capture_code;
122
 
                copy_capture->n = 2 * n;
123
 
 
124
 
                if (sc->ncaptures < n) {
125
 
                    sc->ncaptures = n;
 
367
                if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
 
368
                    return NGX_ERROR;
126
369
                }
127
370
 
128
371
                i++;
129
372
 
130
373
                continue;
131
374
            }
 
375
            }
 
376
#endif
132
377
 
133
378
            if (sc->source->data[i] == '{') {
134
379
                bracket = 1;
177
422
 
178
423
            sc->variables++;
179
424
 
180
 
            index = ngx_http_get_variable_index(sc->cf, &name);
181
 
 
182
 
            if (index == NGX_ERROR) {
183
 
                return NGX_ERROR;
184
 
            }
185
 
 
186
 
            if (sc->flushes) {
187
 
                p = ngx_array_push(*sc->flushes);
188
 
                if (p == NULL) {
189
 
                    return NGX_ERROR;
190
 
                }
191
 
 
192
 
                *p = index;
193
 
            }
194
 
 
195
 
            var_code = ngx_http_script_add_code(*sc->lengths,
196
 
                                            sizeof(ngx_http_script_var_code_t),
197
 
                                            NULL);
198
 
            if (var_code == NULL) {
199
 
                return NGX_ERROR;
200
 
            }
201
 
 
202
 
            var_code->code = (ngx_http_script_code_pt)
203
 
                                            ngx_http_script_copy_var_len_code;
204
 
            var_code->index = (uintptr_t) index;
205
 
 
206
 
 
207
 
            var_code = ngx_http_script_add_code(*sc->values,
208
 
                                            sizeof(ngx_http_script_var_code_t),
209
 
                                            &sc->main);
210
 
            if (var_code == NULL) {
211
 
                return NGX_ERROR;
212
 
            }
213
 
 
214
 
            var_code->code = ngx_http_script_copy_var_code;
215
 
            var_code->index = (uintptr_t) index;
 
425
            if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
 
426
                return NGX_ERROR;
 
427
            }
216
428
 
217
429
            continue;
218
430
        }
221
433
            sc->args = 1;
222
434
            sc->compile_args = 0;
223
435
 
224
 
            code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t),
225
 
                                            NULL);
226
 
            if (code == NULL) {
227
 
                return NGX_ERROR;
228
 
            }
229
 
 
230
 
            *code = (uintptr_t) ngx_http_script_mark_args_code;
231
 
 
232
 
            code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
233
 
                                            &sc->main);
234
 
            if (code == NULL) {
235
 
                return NGX_ERROR;
236
 
            }
237
 
 
238
 
            *code = (uintptr_t) ngx_http_script_start_args_code;
 
436
            if (ngx_http_script_add_args_code(sc) != NGX_OK) {
 
437
                return NGX_ERROR;
 
438
            }
239
439
 
240
440
            i++;
241
441
 
244
444
 
245
445
        name.data = &sc->source->data[i];
246
446
 
247
 
        while (i < sc->source->len
248
 
               && sc->source->data[i] != '$'
249
 
               && !(sc->source->data[i] == '?' && sc->compile_args))
250
 
        {
 
447
        while (i < sc->source->len) {
 
448
 
 
449
            if (sc->source->data[i] == '$') {
 
450
                break;
 
451
            }
 
452
 
 
453
            if (sc->source->data[i] == '?') {
 
454
 
 
455
                sc->args = 1;
 
456
 
 
457
                if (sc->compile_args) {
 
458
                    break;
 
459
                }
 
460
            }
 
461
 
251
462
            i++;
252
463
            name.len++;
253
464
        }
254
465
 
255
466
        sc->size += name.len;
256
467
 
257
 
        copy = ngx_http_script_add_code(*sc->lengths,
258
 
                                        sizeof(ngx_http_script_copy_code_t),
259
 
                                        NULL);
260
 
        if (copy == NULL) {
261
 
            return NGX_ERROR;
262
 
        }
263
 
 
264
 
        copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
265
 
        copy->len = name.len;
266
 
 
267
 
        size = (sizeof(ngx_http_script_copy_code_t) + name.len
268
 
                   + sizeof(uintptr_t) - 1)
269
 
                & ~(sizeof(uintptr_t) - 1);
270
 
 
271
 
        copy = ngx_http_script_add_code(*sc->values, size, &sc->main);
272
 
        if (copy == NULL) {
273
 
            return NGX_ERROR;
274
 
        }
275
 
 
276
 
        copy->code = ngx_http_script_copy_code;
277
 
        copy->len = name.len;
278
 
 
279
 
        ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t),
280
 
                   name.data, name.len);
281
 
    }
282
 
 
283
 
    if (sc->complete_lengths) {
284
 
        code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
285
 
        if (code == NULL) {
286
 
            return NGX_ERROR;
287
 
        }
288
 
 
289
 
        *code = (uintptr_t) NULL;
290
 
    }
291
 
 
292
 
    if (sc->complete_values) {
293
 
        code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
294
 
                                        &sc->main);
295
 
        if (code == NULL) {
296
 
            return NGX_ERROR;
297
 
        }
298
 
 
299
 
        *code = (uintptr_t) NULL;
300
 
    }
301
 
 
302
 
    return NGX_OK;
 
468
        if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
 
469
            != NGX_OK)
 
470
        {
 
471
            return NGX_ERROR;
 
472
        }
 
473
    }
 
474
 
 
475
    return ngx_http_script_done(sc);
303
476
 
304
477
invalid_variable:
305
478
 
341
514
 
342
515
 
343
516
    value->len = len;
344
 
    value->data = ngx_palloc(r->pool, len);
 
517
    value->data = ngx_pnalloc(r->pool, len);
345
518
    if (value->data == NULL) {
346
519
        return NULL;
347
520
    }
376
549
}
377
550
 
378
551
 
 
552
static ngx_int_t
 
553
ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
 
554
{
 
555
    ngx_uint_t   n;
 
556
 
 
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) {
 
561
            return NGX_ERROR;
 
562
        }
 
563
    }
 
564
 
 
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))
 
568
            + sizeof(uintptr_t);
 
569
 
 
570
        *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
 
571
        if (*sc->lengths == NULL) {
 
572
            return NGX_ERROR;
 
573
        }
 
574
    }
 
575
 
 
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))
 
579
                + sizeof(uintptr_t)
 
580
                + sc->source->len
 
581
                + sizeof(uintptr_t) - 1)
 
582
            & ~(sizeof(uintptr_t) - 1);
 
583
 
 
584
        *sc->values = ngx_array_create(sc->cf->pool, n, 1);
 
585
        if (*sc->values == NULL) {
 
586
            return NGX_ERROR;
 
587
        }
 
588
    }
 
589
 
 
590
    sc->variables = 0;
 
591
 
 
592
    return NGX_OK;
 
593
}
 
594
 
 
595
 
 
596
static ngx_int_t
 
597
ngx_http_script_done(ngx_http_script_compile_t *sc)
 
598
{
 
599
    ngx_str_t    zero;
 
600
    uintptr_t   *code;
 
601
 
 
602
    if (sc->zero) {
 
603
 
 
604
        zero.len = 1;
 
605
        zero.data = (u_char *) "\0";
 
606
 
 
607
        if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
 
608
            return NGX_ERROR;
 
609
        }
 
610
    }
 
611
 
 
612
    if (sc->conf_prefix || sc->root_prefix) {
 
613
        if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
 
614
            return NGX_ERROR;
 
615
        }
 
616
    }
 
617
 
 
618
    if (sc->complete_lengths) {
 
619
        code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
 
620
        if (code == NULL) {
 
621
            return NGX_ERROR;
 
622
        }
 
623
 
 
624
        *code = (uintptr_t) NULL;
 
625
    }
 
626
 
 
627
    if (sc->complete_values) {
 
628
        code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
 
629
                                        &sc->main);
 
630
        if (code == NULL) {
 
631
            return NGX_ERROR;
 
632
        }
 
633
 
 
634
        *code = (uintptr_t) NULL;
 
635
    }
 
636
 
 
637
    return NGX_OK;
 
638
}
 
639
 
 
640
 
379
641
void *
380
642
ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
381
643
{
400
662
 
401
663
    new = ngx_array_push_n(codes, size);
402
664
    if (new == NULL) {
403
 
        return NGX_CONF_ERROR;
 
665
        return NULL;
404
666
    }
405
667
 
406
668
    if (code) {
414
676
}
415
677
 
416
678
 
 
679
static ngx_int_t
 
680
ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
 
681
    ngx_uint_t last)
 
682
{
 
683
    u_char                       *p;
 
684
    size_t                        size, len, zero;
 
685
    ngx_http_script_copy_code_t  *code;
 
686
 
 
687
    zero = (sc->zero && last);
 
688
    len = value->len + zero;
 
689
 
 
690
    code = ngx_http_script_add_code(*sc->lengths,
 
691
                                    sizeof(ngx_http_script_copy_code_t), NULL);
 
692
    if (code == NULL) {
 
693
        return NGX_ERROR;
 
694
    }
 
695
 
 
696
    code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
 
697
    code->len = len;
 
698
 
 
699
    size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
 
700
            & ~(sizeof(uintptr_t) - 1);
 
701
 
 
702
    code = ngx_http_script_add_code(*sc->values, size, &sc->main);
 
703
    if (code == NULL) {
 
704
        return NGX_ERROR;
 
705
    }
 
706
 
 
707
    code->code = ngx_http_script_copy_code;
 
708
    code->len = len;
 
709
 
 
710
    p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
 
711
                   value->data, value->len);
 
712
 
 
713
    if (zero) {
 
714
        *p = '\0';
 
715
        sc->zero = 0;
 
716
    }
 
717
 
 
718
    return NGX_OK;
 
719
}
 
720
 
 
721
 
417
722
size_t
418
723
ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
419
724
{
430
735
void
431
736
ngx_http_script_copy_code(ngx_http_script_engine_t *e)
432
737
{
 
738
    u_char                       *p;
433
739
    ngx_http_script_copy_code_t  *code;
434
740
 
435
741
    code = (ngx_http_script_copy_code_t *) e->ip;
436
742
 
 
743
    p = e->pos;
 
744
 
437
745
    if (!e->skip) {
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),
439
747
                          code->len);
440
748
    }
441
749
 
442
750
    e->ip += sizeof(ngx_http_script_copy_code_t)
443
751
          + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
444
752
 
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);
 
755
}
 
756
 
 
757
 
 
758
static ngx_int_t
 
759
ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name)
 
760
{
 
761
    ngx_int_t                    index, *p;
 
762
    ngx_http_script_var_code_t  *code;
 
763
 
 
764
    index = ngx_http_get_variable_index(sc->cf, name);
 
765
 
 
766
    if (index == NGX_ERROR) {
 
767
        return NGX_ERROR;
 
768
    }
 
769
 
 
770
    if (sc->flushes) {
 
771
        p = ngx_array_push(*sc->flushes);
 
772
        if (p == NULL) {
 
773
            return NGX_ERROR;
 
774
        }
 
775
 
 
776
        *p = index;
 
777
    }
 
778
 
 
779
    code = ngx_http_script_add_code(*sc->lengths,
 
780
                                    sizeof(ngx_http_script_var_code_t), NULL);
 
781
    if (code == NULL) {
 
782
        return NGX_ERROR;
 
783
    }
 
784
 
 
785
    code->code = (ngx_http_script_code_pt) ngx_http_script_copy_var_len_code;
 
786
    code->index = (uintptr_t) index;
 
787
 
 
788
    code = ngx_http_script_add_code(*sc->values,
 
789
                                    sizeof(ngx_http_script_var_code_t),
 
790
                                    &sc->main);
 
791
    if (code == NULL) {
 
792
        return NGX_ERROR;
 
793
    }
 
794
 
 
795
    code->code = ngx_http_script_copy_var_code;
 
796
    code->index = (uintptr_t) index;
 
797
 
 
798
    return NGX_OK;
447
799
}
448
800
 
449
801
 
475
827
void
476
828
ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
477
829
{
 
830
    u_char                      *p;
478
831
    ngx_http_variable_value_t   *value;
479
832
    ngx_http_script_var_code_t  *code;
480
833
 
492
845
        }
493
846
 
494
847
        if (value && !value->not_found) {
495
 
            e->pos = ngx_copy(e->pos, value->data, value->len);
 
848
            p = e->pos;
 
849
            e->pos = ngx_copy(p, value->data, value->len);
496
850
 
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);
500
 
        }
501
 
    }
502
 
}
503
 
 
504
 
 
505
 
size_t
506
 
ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
507
 
{
508
 
    ngx_http_script_copy_capture_code_t  *code;
509
 
 
510
 
    code = (ngx_http_script_copy_capture_code_t *) e->ip;
511
 
 
512
 
    e->ip += sizeof(ngx_http_script_copy_capture_code_t);
513
 
 
514
 
    if (code->n < e->ncaptures) {
515
 
        if ((e->is_args || e->quote)
516
 
            && (e->request->quoted_uri || e->request->plus_in_uri))
517
 
        {
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],
522
 
                                NGX_ESCAPE_ARGS);
523
 
        } else {
524
 
            return e->captures[code->n + 1] - e->captures[code->n];
525
 
        }
526
 
    }
527
 
 
528
 
    return 0;
529
 
}
530
 
 
531
 
 
532
 
void
533
 
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
534
 
{
535
 
    ngx_http_script_copy_capture_code_t  *code;
536
 
 
537
 
    code = (ngx_http_script_copy_capture_code_t *) e->ip;
538
 
 
539
 
    e->ip += sizeof(ngx_http_script_copy_capture_code_t);
540
 
 
541
 
    if (code->n < e->ncaptures) {
542
 
        if ((e->is_args || e->quote)
543
 
            && (e->request->quoted_uri || e->request->plus_in_uri))
544
 
        {
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],
548
 
                                NGX_ESCAPE_ARGS);
549
 
        } else {
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]);
553
 
        }
554
 
    }
555
 
 
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);
 
854
        }
 
855
    }
 
856
}
 
857
 
 
858
 
 
859
static ngx_int_t
 
860
ngx_http_script_add_args_code(ngx_http_script_compile_t *sc)
 
861
{
 
862
    uintptr_t   *code;
 
863
 
 
864
    code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
 
865
    if (code == NULL) {
 
866
        return NGX_ERROR;
 
867
    }
 
868
 
 
869
    *code = (uintptr_t) ngx_http_script_mark_args_code;
 
870
 
 
871
    code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main);
 
872
    if (code == NULL) {
 
873
        return NGX_ERROR;
 
874
    }
 
875
 
 
876
    *code = (uintptr_t) ngx_http_script_start_args_code;
 
877
 
 
878
    return NGX_OK;
558
879
}
559
880
 
560
881
 
574
895
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
575
896
                   "http script args");
576
897
 
 
898
    e->is_args = 1;
577
899
    e->args = e->pos;
578
900
    e->ip += sizeof(uintptr_t);
579
901
}
580
902
 
581
903
 
582
 
 
583
904
#if (NGX_PCRE)
584
905
 
585
906
void
608
929
        e->line.data = e->sp->data;
609
930
    }
610
931
 
611
 
    rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures);
 
932
    rc = ngx_http_regex_exec(r, code->regex, &e->line);
612
933
 
613
 
    if (rc == NGX_REGEX_NO_MATCHED) {
614
 
        if (e->log) {
 
934
    if (rc == NGX_DECLINED) {
 
935
        if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
615
936
            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
616
937
                          "\"%V\" does not match \"%V\"",
617
938
                          &code->name, &e->line);
618
939
        }
619
940
 
620
 
        e->ncaptures = 0;
 
941
        r->ncaptures = 0;
621
942
 
622
943
        if (code->test) {
623
944
            if (code->negative_test) {
639
960
        return;
640
961
    }
641
962
 
642
 
    if (rc < 0) {
643
 
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
644
 
                      ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
645
 
                      rc, &e->line, &code->name);
646
 
 
 
963
    if (rc == NGX_ERROR) {
647
964
        e->ip = ngx_http_script_exit;
648
965
        e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
649
966
        return;
650
967
    }
651
968
 
652
 
    if (e->log) {
 
969
    if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
653
970
        ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
654
971
                      "\"%V\" matches \"%V\"", &code->name, &e->line);
655
972
    }
656
973
 
657
 
    e->ncaptures = code->ncaptures;
658
 
 
659
974
    if (code->test) {
660
975
        if (code->negative_test) {
661
976
            e->sp->len = 0;
698
1013
        e->buf.len = code->size;
699
1014
 
700
1015
        if (code->uri) {
701
 
            if (rc && (r->quoted_uri || r->plus_in_uri)) {
 
1016
            if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
702
1017
                e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
703
1018
                                                 NGX_ESCAPE_ARGS);
704
1019
            }
705
1020
        }
706
1021
 
707
 
        for (n = 1; n < (ngx_uint_t) rc; n++) {
708
 
            e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n];
 
1022
        for (n = 2; n < r->ncaptures; n += 2) {
 
1023
            e->buf.len += r->captures[n + 1] - r->captures[n];
709
1024
        }
710
1025
 
711
1026
    } else {
714
1029
        le.ip = code->lengths->elts;
715
1030
        le.line = e->line;
716
1031
        le.request = r;
717
 
        le.captures = e->captures;
718
 
        le.ncaptures = e->ncaptures;
719
1032
        le.quote = code->redirect;
720
1033
 
721
1034
        len = 0;
726
1039
        }
727
1040
 
728
1041
        e->buf.len = len;
729
 
        e->is_args = le.is_args;
730
1042
    }
731
1043
 
732
1044
    if (code->add_args && r->args.len) {
733
1045
        e->buf.len += r->args.len + 1;
734
1046
    }
735
1047
 
736
 
    e->buf.data = ngx_palloc(r->pool, e->buf.len);
 
1048
    e->buf.data = ngx_pnalloc(r->pool, e->buf.len);
737
1049
    if (e->buf.data == NULL) {
738
1050
        e->ip = ngx_http_script_exit;
739
1051
        e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
773
1085
                         NGX_UNESCAPE_REDIRECT);
774
1086
 
775
1087
        if (src < e->pos) {
776
 
            dst = ngx_copy(dst, src, e->pos - src);
 
1088
            dst = ngx_movemem(dst, src, e->pos - src);
777
1089
        }
778
1090
 
779
1091
        e->pos = dst;
785
1097
 
786
1098
        e->buf.len = e->pos - e->buf.data;
787
1099
 
788
 
        if (e->log) {
 
1100
        if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
789
1101
            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
790
1102
                          "rewritten redirect: \"%V\"", &e->buf);
791
1103
        }
792
1104
 
 
1105
        ngx_http_clear_location(r);
 
1106
 
793
1107
        r->headers_out.location = ngx_list_push(&r->headers_out.headers);
794
1108
        if (r->headers_out.location == NULL) {
795
1109
            e->ip = ngx_http_script_exit;
798
1112
        }
799
1113
 
800
1114
        r->headers_out.location->hash = 1;
801
 
        r->headers_out.location->key.len = sizeof("Location") - 1;
802
 
        r->headers_out.location->key.data = (u_char *) "Location";
 
1115
        ngx_str_set(&r->headers_out.location->key, "Location");
803
1116
        r->headers_out.location->value = e->buf;
804
1117
 
805
1118
        e->ip += sizeof(ngx_http_script_regex_end_code_t);
827
1140
        }
828
1141
    }
829
1142
 
830
 
    if (e->log) {
 
1143
    if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
831
1144
        ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
832
1145
                      "rewritten data: \"%V\", args: \"%V\"",
833
1146
                      &e->buf, &r->args);
844
1157
            return;
845
1158
        }
846
1159
 
847
 
        if (ngx_http_set_exten(r) != NGX_OK) {
848
 
            e->ip = ngx_http_script_exit;
849
 
            e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
850
 
            return;
851
 
        }
 
1160
        ngx_http_set_exten(r);
852
1161
    }
853
1162
 
854
1163
    e->ip += sizeof(ngx_http_script_regex_end_code_t);
855
1164
}
856
1165
 
 
1166
 
 
1167
static ngx_int_t
 
1168
ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
 
1169
{
 
1170
    ngx_http_script_copy_capture_code_t  *code;
 
1171
 
 
1172
    code = ngx_http_script_add_code(*sc->lengths,
 
1173
                                    sizeof(ngx_http_script_copy_capture_code_t),
 
1174
                                    NULL);
 
1175
    if (code == NULL) {
 
1176
        return NGX_ERROR;
 
1177
    }
 
1178
 
 
1179
    code->code = (ngx_http_script_code_pt)
 
1180
                      ngx_http_script_copy_capture_len_code;
 
1181
    code->n = 2 * n;
 
1182
 
 
1183
 
 
1184
    code = ngx_http_script_add_code(*sc->values,
 
1185
                                    sizeof(ngx_http_script_copy_capture_code_t),
 
1186
                                    &sc->main);
 
1187
    if (code == NULL) {
 
1188
        return NGX_ERROR;
 
1189
    }
 
1190
 
 
1191
    code->code = ngx_http_script_copy_capture_code;
 
1192
    code->n = 2 * n;
 
1193
 
 
1194
    if (sc->ncaptures < n) {
 
1195
        sc->ncaptures = n;
 
1196
    }
 
1197
 
 
1198
    return NGX_OK;
 
1199
}
 
1200
 
 
1201
 
 
1202
size_t
 
1203
ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
 
1204
{
 
1205
    int                                  *cap;
 
1206
    u_char                               *p;
 
1207
    ngx_uint_t                            n;
 
1208
    ngx_http_request_t                   *r;
 
1209
    ngx_http_script_copy_capture_code_t  *code;
 
1210
 
 
1211
    r = e->request;
 
1212
 
 
1213
    code = (ngx_http_script_copy_capture_code_t *) e->ip;
 
1214
 
 
1215
    e->ip += sizeof(ngx_http_script_copy_capture_code_t);
 
1216
 
 
1217
    n = code->n;
 
1218
 
 
1219
    if (n < r->ncaptures) {
 
1220
 
 
1221
        cap = r->captures;
 
1222
 
 
1223
        if ((e->is_args || e->quote)
 
1224
            && (e->request->quoted_uri || e->request->plus_in_uri))
 
1225
        {
 
1226
            p = r->captures_data;
 
1227
 
 
1228
            return cap[n + 1] - cap[n]
 
1229
                   + 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n],
 
1230
                                        NGX_ESCAPE_ARGS);
 
1231
        } else {
 
1232
            return cap[n + 1] - cap[n];
 
1233
        }
 
1234
    }
 
1235
 
 
1236
    return 0;
 
1237
}
 
1238
 
 
1239
 
 
1240
void
 
1241
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
 
1242
{
 
1243
    int                                  *cap;
 
1244
    u_char                               *p, *pos;
 
1245
    ngx_uint_t                            n;
 
1246
    ngx_http_request_t                   *r;
 
1247
    ngx_http_script_copy_capture_code_t  *code;
 
1248
 
 
1249
    r = e->request;
 
1250
 
 
1251
    code = (ngx_http_script_copy_capture_code_t *) e->ip;
 
1252
 
 
1253
    e->ip += sizeof(ngx_http_script_copy_capture_code_t);
 
1254
 
 
1255
    n = code->n;
 
1256
 
 
1257
    pos = e->pos;
 
1258
 
 
1259
    if (n < r->ncaptures) {
 
1260
 
 
1261
        cap = r->captures;
 
1262
        p = r->captures_data;
 
1263
 
 
1264
        if ((e->is_args || e->quote)
 
1265
            && (e->request->quoted_uri || e->request->plus_in_uri))
 
1266
        {
 
1267
            e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
 
1268
                                               cap[n + 1] - cap[n],
 
1269
                                               NGX_ESCAPE_ARGS);
 
1270
        } else {
 
1271
            e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
 
1272
        }
 
1273
    }
 
1274
 
 
1275
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
 
1276
                   "http script capture: \"%*s\"", e->pos - pos, pos);
 
1277
}
 
1278
 
857
1279
#endif
858
1280
 
859
1281
 
 
1282
static ngx_int_t
 
1283
ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
 
1284
{
 
1285
    ngx_http_script_full_name_code_t  *code;
 
1286
 
 
1287
    code = ngx_http_script_add_code(*sc->lengths,
 
1288
                                    sizeof(ngx_http_script_full_name_code_t),
 
1289
                                    NULL);
 
1290
    if (code == NULL) {
 
1291
        return NGX_ERROR;
 
1292
    }
 
1293
 
 
1294
    code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
 
1295
    code->conf_prefix = sc->conf_prefix;
 
1296
 
 
1297
    code = ngx_http_script_add_code(*sc->values,
 
1298
                                    sizeof(ngx_http_script_full_name_code_t),
 
1299
                                    &sc->main);
 
1300
    if (code == NULL) {
 
1301
        return NGX_ERROR;
 
1302
    }
 
1303
 
 
1304
    code->code = ngx_http_script_full_name_code;
 
1305
    code->conf_prefix = sc->conf_prefix;
 
1306
 
 
1307
    return NGX_OK;
 
1308
}
 
1309
 
 
1310
 
 
1311
static size_t
 
1312
ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
 
1313
{
 
1314
    ngx_http_script_full_name_code_t  *code;
 
1315
 
 
1316
    code = (ngx_http_script_full_name_code_t *) e->ip;
 
1317
 
 
1318
    e->ip += sizeof(ngx_http_script_full_name_code_t);
 
1319
 
 
1320
    return code->conf_prefix ? ngx_cycle->conf_prefix.len:
 
1321
                               ngx_cycle->prefix.len;
 
1322
}
 
1323
 
 
1324
 
 
1325
static void
 
1326
ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
 
1327
{
 
1328
    ngx_http_script_full_name_code_t  *code;
 
1329
 
 
1330
    ngx_str_t  value;
 
1331
 
 
1332
    code = (ngx_http_script_full_name_code_t *) e->ip;
 
1333
 
 
1334
    value.data = e->buf.data;
 
1335
    value.len = e->pos - e->buf.data;
 
1336
 
 
1337
    if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
 
1338
        != NGX_OK)
 
1339
    {
 
1340
        e->ip = ngx_http_script_exit;
 
1341
        e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1342
        return;
 
1343
    }
 
1344
 
 
1345
    e->buf = value;
 
1346
 
 
1347
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
 
1348
                   "http script fullname: \"%V\"", &value);
 
1349
 
 
1350
    e->ip += sizeof(ngx_http_script_full_name_code_t);
 
1351
}
 
1352
 
 
1353
 
860
1354
void
861
1355
ngx_http_script_return_code(ngx_http_script_engine_t *e)
862
1356
{
864
1358
 
865
1359
    code = (ngx_http_script_return_code_t *) e->ip;
866
1360
 
867
 
    e->status = code->status;
868
 
 
869
 
    if (code->status == NGX_HTTP_NO_CONTENT) {
870
 
        e->request->header_only = 1;
871
 
        e->request->zero_body = 1;
 
1361
    if (code->status < NGX_HTTP_BAD_REQUEST
 
1362
        || code->text.value.len
 
1363
        || code->text.lengths)
 
1364
    {
 
1365
        e->status = ngx_http_send_response(e->request, code->status, NULL,
 
1366
                                           &code->text);
 
1367
    } else {
 
1368
        e->status = code->status;
872
1369
    }
873
1370
 
874
 
    e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t);
 
1371
    e->ip = ngx_http_script_exit;
875
1372
}
876
1373
 
877
1374
 
896
1393
 
897
1394
    e->sp--;
898
1395
 
899
 
    if (e->sp->len && e->sp->data[0] != '0') {
 
1396
    if (e->sp->len && (e->sp->len !=1 || e->sp->data[0] != '0')) {
900
1397
        if (code->loc_conf) {
901
1398
            e->request->loc_conf = code->loc_conf;
902
1399
            ngx_http_update_location_config(e->request);
927
1424
 
928
1425
    e->ip += sizeof(uintptr_t);
929
1426
 
930
 
    if (val->len == res->len && ngx_strncmp(val->data, res->data, res->len)
931
 
        == 0)
 
1427
    if (val->len == res->len
 
1428
        && ngx_strncmp(val->data, res->data, res->len) == 0)
932
1429
    {
933
1430
        *res = ngx_http_variable_true_value;
934
1431
        return;
955
1452
 
956
1453
    e->ip += sizeof(uintptr_t);
957
1454
 
958
 
    if (val->len == res->len && ngx_strncmp(val->data, res->data, res->len)
959
 
        == 0)
 
1455
    if (val->len == res->len
 
1456
        && ngx_strncmp(val->data, res->data, res->len) == 0)
960
1457
    {
961
1458
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
962
1459
                       "http script not equal: no");
994
1491
 
995
1492
    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
996
1493
 
997
 
    of.test_dir = 0;
 
1494
    ngx_memzero(&of, sizeof(ngx_open_file_info_t));
 
1495
 
 
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;
 
1500
    of.test_only = 1;
1000
1501
    of.errors = clcf->open_file_cache_errors;
1001
1502
    of.events = clcf->open_file_cache_events;
1002
1503
 
 
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;
 
1507
        return;
 
1508
    }
 
1509
 
1003
1510
    if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
1004
1511
        != NGX_OK)
1005
1512
    {
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)
 
1516
        {
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);
1009
1519
        }
1010
1520
 
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:
1017
 
             goto false;
 
1527
             goto false_value;
1018
1528
 
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:
1023
 
             goto true;
 
1533
             goto true_value;
1024
1534
        }
1025
1535
 
1026
 
        goto false;
 
1536
        goto false_value;
1027
1537
    }
1028
1538
 
1029
1539
    switch (code->op) {
1030
1540
    case ngx_http_script_file_plain:
1031
1541
        if (of.is_file) {
1032
 
             goto true;
 
1542
             goto true_value;
1033
1543
        }
1034
 
        goto false;
 
1544
        goto false_value;
1035
1545
 
1036
1546
    case ngx_http_script_file_not_plain:
1037
1547
        if (of.is_file) {
1038
 
            goto false;
 
1548
            goto false_value;
1039
1549
        }
1040
 
        goto true;
 
1550
        goto true_value;
1041
1551
 
1042
1552
    case ngx_http_script_file_dir:
1043
1553
        if (of.is_dir) {
1044
 
             goto true;
 
1554
             goto true_value;
1045
1555
        }
1046
 
        goto false;
 
1556
        goto false_value;
1047
1557
 
1048
1558
    case ngx_http_script_file_not_dir:
1049
1559
        if (of.is_dir) {
1050
 
            goto false;
 
1560
            goto false_value;
1051
1561
        }
1052
 
        goto true;
 
1562
        goto true_value;
1053
1563
 
1054
1564
    case ngx_http_script_file_exists:
1055
1565
        if (of.is_file || of.is_dir || of.is_link) {
1056
 
             goto true;
 
1566
             goto true_value;
1057
1567
        }
1058
 
        goto false;
 
1568
        goto false_value;
1059
1569
 
1060
1570
    case ngx_http_script_file_not_exists:
1061
1571
        if (of.is_file || of.is_dir || of.is_link) {
1062
 
            goto false;
 
1572
            goto false_value;
1063
1573
        }
1064
 
        goto true;
 
1574
        goto true_value;
1065
1575
 
1066
1576
    case ngx_http_script_file_exec:
1067
1577
        if (of.is_exec) {
1068
 
             goto true;
 
1578
             goto true_value;
1069
1579
        }
1070
 
        goto false;
 
1580
        goto false_value;
1071
1581
 
1072
1582
    case ngx_http_script_file_not_exec:
1073
1583
        if (of.is_exec) {
1074
 
            goto false;
 
1584
            goto false_value;
1075
1585
        }
1076
 
        goto true;
 
1586
        goto true_value;
1077
1587
    }
1078
1588
 
1079
 
false:
 
1589
false_value:
1080
1590
 
1081
1591
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1082
1592
                   "http script file op false");
1084
1594
    *value = ngx_http_variable_null_value;
1085
1595
    return;
1086
1596
 
1087
 
true:
 
1597
true_value:
1088
1598
 
1089
1599
    *value = ngx_http_variable_true_value;
1090
1600
    return;
1111
1621
    le.ip = code->lengths->elts;
1112
1622
    le.line = e->line;
1113
1623
    le.request = e->request;
1114
 
    le.captures = e->captures;
1115
 
    le.ncaptures = e->ncaptures;
1116
1624
    le.quote = e->quote;
1117
1625
 
1118
1626
    for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
1120
1628
    }
1121
1629
 
1122
1630
    e->buf.len = len;
1123
 
    e->buf.data = ngx_palloc(e->request->pool, len);
 
1631
    e->buf.data = ngx_pnalloc(e->request->pool, len);
1124
1632
    if (e->buf.data == NULL) {
1125
1633
        e->ip = ngx_http_script_exit;
1126
1634
        e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
1160
1668
    ngx_http_request_t          *r;
1161
1669
    ngx_http_script_var_code_t  *code;
1162
1670
 
1163
 
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
1164
 
                   "http script set var");
1165
 
 
1166
1671
    code = (ngx_http_script_var_code_t *) e->ip;
1167
1672
 
1168
1673
    e->ip += sizeof(ngx_http_script_var_code_t);
1176
1681
    r->variables[code->index].no_cacheable = 0;
1177
1682
    r->variables[code->index].not_found = 0;
1178
1683
    r->variables[code->index].data = e->sp->data;
 
1684
 
 
1685
#if (NGX_DEBUG)
 
1686
    {
 
1687
    ngx_http_variable_t        *v;
 
1688
    ngx_http_core_main_conf_t  *cmcf;
 
1689
 
 
1690
    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
 
1691
 
 
1692
    v = cmcf->variables.elts;
 
1693
 
 
1694
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
 
1695
                   "http script set $%V", &v[code->index].name);
 
1696
    }
 
1697
#endif
1179
1698
}
1180
1699
 
1181
1700