⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_http_script.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>#define ngx_http_script_exit  (u_char *) &ngx_http_script_exit_codestatic uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;ngx_uint_tngx_http_script_variables_count(ngx_str_t *value){    ngx_uint_t  i, n;    for (n = 0, i = 0; i < value->len; i++) {        if (value->data[i] == '$') {            n++;        }    }    return n;}ngx_int_tngx_http_script_compile(ngx_http_script_compile_t *sc){    u_char                                ch;    size_t                                size;    ngx_int_t                             index, *p;    ngx_str_t                             name;    uintptr_t                            *code;    ngx_uint_t                            i, n, bracket;    ngx_http_script_var_code_t           *var_code;    ngx_http_script_copy_code_t          *copy;    ngx_http_script_copy_capture_code_t  *copy_capture;    if (sc->flushes && *sc->flushes == NULL) {        n = sc->variables ? sc->variables : 1;        *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));        if (*sc->flushes == NULL) {            return NGX_ERROR;        }    }    if (*sc->lengths == NULL) {        n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)                             + sizeof(ngx_http_script_var_code_t))            + sizeof(uintptr_t);        *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);        if (*sc->lengths == NULL) {            return NGX_ERROR;        }    }    if (*sc->values == NULL) {        n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)                              + sizeof(ngx_http_script_var_code_t))                + sizeof(uintptr_t)                + sc->source->len                + sizeof(uintptr_t) - 1)            & ~(sizeof(uintptr_t) - 1);        *sc->values = ngx_array_create(sc->cf->pool, n, 1);        if (*sc->values == NULL) {            return NGX_ERROR;        }    }    sc->variables = 0;    for (i = 0; i < sc->source->len; /* void */ ) {        name.len = 0;        if (sc->source->data[i] == '$') {            if (++i == sc->source->len) {                goto invalid_variable;            }            if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {                n = sc->source->data[i] - '0';                if (sc->captures_mask & (1 << n)) {                    sc->dup_capture = 1;                }                sc->captures_mask |= 1 << n;                copy_capture = ngx_http_script_add_code(*sc->lengths,                                   sizeof(ngx_http_script_copy_capture_code_t),                                   NULL);                if (copy_capture == NULL) {                    return NGX_ERROR;                }                copy_capture->code = (ngx_http_script_code_pt)                                         ngx_http_script_copy_capture_len_code;                copy_capture->n = 2 * n;                copy_capture = ngx_http_script_add_code(*sc->values,                                   sizeof(ngx_http_script_copy_capture_code_t),                                   &sc->main);                if (copy_capture == NULL) {                    return NGX_ERROR;                }                copy_capture->code = ngx_http_script_copy_capture_code;                copy_capture->n = 2 * n;                if (sc->ncaptures < n) {                    sc->ncaptures = n;                }                i++;                continue;            }            if (sc->source->data[i] == '{') {                bracket = 1;                if (++i == sc->source->len) {                    goto invalid_variable;                }                name.data = &sc->source->data[i];            } else {                bracket = 0;                name.data = &sc->source->data[i];            }            for ( /* void */ ; i < sc->source->len; i++, name.len++) {                ch = sc->source->data[i];                if (ch == '}' && bracket) {                    i++;                    bracket = 0;                    break;                }                if ((ch >= 'A' && ch <= 'Z')                    || (ch >= 'a' && ch <= 'z')                    || (ch >= '0' && ch <= '9')                    || ch == '_')                {                    continue;                }                break;            }            if (bracket) {                ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,                                   "the closing bracket in \"%V\" "                                   "variable is missing", &name);                return NGX_ERROR;            }            if (name.len == 0) {                goto invalid_variable;            }            sc->variables++;            index = ngx_http_get_variable_index(sc->cf, &name);            if (index == NGX_ERROR) {                return NGX_ERROR;            }            if (sc->flushes) {                p = ngx_array_push(*sc->flushes);                if (p == NULL) {                    return NGX_ERROR;                }                *p = index;            }            var_code = ngx_http_script_add_code(*sc->lengths,                                            sizeof(ngx_http_script_var_code_t),                                            NULL);            if (var_code == NULL) {                return NGX_ERROR;            }            var_code->code = (ngx_http_script_code_pt)                                            ngx_http_script_copy_var_len_code;            var_code->index = (uintptr_t) index;            var_code = ngx_http_script_add_code(*sc->values,                                            sizeof(ngx_http_script_var_code_t),                                            &sc->main);            if (var_code == NULL) {                return NGX_ERROR;            }            var_code->code = ngx_http_script_copy_var_code;            var_code->index = (uintptr_t) index;            continue;        }        if (sc->source->data[i] == '?' && sc->compile_args) {            sc->args = 1;            sc->compile_args = 0;            code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t),                                            NULL);            if (code == NULL) {                return NGX_ERROR;            }            *code = (uintptr_t) ngx_http_script_mark_args_code;            code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),                                            &sc->main);            if (code == NULL) {                return NGX_ERROR;            }            *code = (uintptr_t) ngx_http_script_start_args_code;            i++;            continue;        }        name.data = &sc->source->data[i];        while (i < sc->source->len               && sc->source->data[i] != '$'               && !(sc->source->data[i] == '?' && sc->compile_args))        {            i++;            name.len++;        }        sc->size += name.len;        copy = ngx_http_script_add_code(*sc->lengths,                                        sizeof(ngx_http_script_copy_code_t),                                        NULL);        if (copy == NULL) {            return NGX_ERROR;        }        copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;        copy->len = name.len;        size = (sizeof(ngx_http_script_copy_code_t) + name.len                   + sizeof(uintptr_t) - 1)                & ~(sizeof(uintptr_t) - 1);        copy = ngx_http_script_add_code(*sc->values, size, &sc->main);        if (copy == NULL) {            return NGX_ERROR;        }        copy->code = ngx_http_script_copy_code;        copy->len = name.len;        ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t),                   name.data, name.len);    }    if (sc->complete_lengths) {        code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);        if (code == NULL) {            return NGX_ERROR;        }        *code = (uintptr_t) NULL;    }    if (sc->complete_values) {        code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),                                        &sc->main);        if (code == NULL) {            return NGX_ERROR;        }        *code = (uintptr_t) NULL;    }    return NGX_OK;invalid_variable:    ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");    return NGX_ERROR;}u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,    void *code_lengths, size_t len, void *code_values){    ngx_uint_t                    i;    ngx_http_script_code_pt       code;    ngx_http_script_len_code_pt   lcode;    ngx_http_script_engine_t      e;    ngx_http_core_main_conf_t    *cmcf;    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);    for (i = 0; i < cmcf->variables.nelts; i++) {        if (r->variables[i].no_cacheable) {            r->variables[i].valid = 0;            r->variables[i].not_found = 0;        }    }    ngx_memzero(&e, sizeof(ngx_http_script_engine_t));    e.ip = code_lengths;    e.request = r;    e.flushed = 1;    while (*(uintptr_t *) e.ip) {        lcode = *(ngx_http_script_len_code_pt *) e.ip;        len += lcode(&e);    }    value->len = len;    value->data = ngx_palloc(r->pool, len);    if (value->data == NULL) {        return NULL;    }    e.ip = code_values;    e.pos = value->data;    while (*(uintptr_t *) e.ip) {        code = *(ngx_http_script_code_pt *) e.ip;        code((ngx_http_script_engine_t *) &e);    }    return e.pos;}voidngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,    ngx_array_t *indices){    ngx_uint_t  n, *index;    if (indices) {        index = indices->elts;        for (n = 0; n < indices->nelts; n++) {            if (r->variables[index[n]].no_cacheable) {                r->variables[index[n]].valid = 0;                r->variables[index[n]].not_found = 0;            }        }    }}void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size){    if (*codes == NULL) {        *codes = ngx_array_create(pool, 256, 1);        if (*codes == NULL) {            return NULL;        }    }    return ngx_array_push_n(*codes, size);}void *ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code){    u_char  *elts, **p;    void    *new;    elts = codes->elts;    new = ngx_array_push_n(codes, size);    if (new == NULL) {        return NGX_CONF_ERROR;    }    if (code) {        if (elts != codes->elts) {            p = code;            *p += (u_char *) codes->elts - elts;        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -