📄 ngx_http_script.c
字号:
/* * 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 + -