Mercurial > hg > nginx
view src/http/ngx_http_script.c @ 647:95d7da23ea53 release-0.3.45
nginx-0.3.45-RELEASE import
*) Feature: the "ssl_verify_client", "ssl_verify_depth", and
"ssl_client_certificate" directives.
*) Change: the $request_method variable now returns the main request
method.
*) Change: the ° symbol codes were changed in koi-win conversion
table.
*) Feature: the euro and N symbols were added to koi-win conversion
table.
*) Bugfix: if nginx distributed the requests among several backends and
some backend failed, then requests intended for this backend was
directed to one live backend only instead of being distributed among
the rest.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 06 May 2006 16:28:56 +0000 |
parents | 5e8fb59c18c1 |
children | 7cbef16c71a1 |
line wrap: on
line source
/* * 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_code static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL; ngx_uint_t ngx_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_t ngx_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->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_http_script_code_pt code; ngx_http_script_len_code_pt lcode; ngx_http_script_engine_t e; 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; } void ngx_http_script_flush_no_cachable_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_cachable) { 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; } } return new; } size_t ngx_http_script_copy_len_code(ngx_http_script_engine_t *e) { ngx_http_script_copy_code_t *code; code = (ngx_http_script_copy_code_t *) e->ip; e->ip += sizeof(ngx_http_script_copy_code_t); return code->len; } void ngx_http_script_copy_code(ngx_http_script_engine_t *e) { ngx_http_script_copy_code_t *code; code = (ngx_http_script_copy_code_t *) e->ip; if (!e->skip) { e->pos = ngx_copy(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t), code->len); } e->ip += sizeof(ngx_http_script_copy_code_t) + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); if (e->log) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script copy: \"%V\"", &e->buf); } } size_t ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e) { ngx_http_variable_value_t *value; ngx_http_script_var_code_t *code; code = (ngx_http_script_var_code_t *) e->ip; e->ip += sizeof(ngx_http_script_var_code_t); if (e->flushed) { value = ngx_http_get_indexed_variable(e->request, code->index); } else { value = ngx_http_get_flushed_variable(e->request, code->index); } if (value && !value->not_found) { return value->len; } return 0; } void ngx_http_script_copy_var_code(ngx_http_script_engine_t *e) { ngx_http_variable_value_t *value; ngx_http_script_var_code_t *code; code = (ngx_http_script_var_code_t *) e->ip; e->ip += sizeof(ngx_http_script_var_code_t); if (!e->skip) { if (e->flushed) { value = ngx_http_get_indexed_variable(e->request, code->index); } else { value = ngx_http_get_flushed_variable(e->request, code->index); } if (value && !value->not_found) { e->pos = ngx_copy(e->pos, value->data, value->len); if (e->log) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script var: \"%V\"", &e->buf); } } } } size_t ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) { ngx_http_script_copy_capture_code_t *code; code = (ngx_http_script_copy_capture_code_t *) e->ip; e->ip += sizeof(ngx_http_script_copy_capture_code_t); if (code->n < e->ncaptures) { if ((e->args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri)) { return e->captures[code->n + 1] - e->captures[code->n] + ngx_escape_uri(NULL, &e->line.data[e->captures[code->n]], e->captures[code->n + 1] - e->captures[code->n], NGX_ESCAPE_ARGS); } else { return e->captures[code->n + 1] - e->captures[code->n]; } } return 0; } void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e) { ngx_http_script_copy_capture_code_t *code; code = (ngx_http_script_copy_capture_code_t *) e->ip; e->ip += sizeof(ngx_http_script_copy_capture_code_t); if (code->n < e->ncaptures) { if ((e->args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri)) { e->pos = (u_char *) ngx_escape_uri(e->pos, &e->line.data[e->captures[code->n]], e->captures[code->n + 1] - e->captures[code->n], NGX_ESCAPE_ARGS); } else { e->pos = ngx_copy(e->pos, &e->line.data[e->captures[code->n]], e->captures[code->n + 1] - e->captures[code->n]); } } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script capture: \"%V\"", &e->buf); } void ngx_http_script_start_args_code(ngx_http_script_engine_t *e) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script args"); e->args = e->pos; e->ip += sizeof(uintptr_t); } #if (NGX_PCRE) void ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) { size_t len; ngx_int_t rc; ngx_uint_t n; ngx_http_request_t *r; ngx_http_script_engine_t le; ngx_http_script_len_code_pt lcode; ngx_http_script_regex_code_t *code; code = (ngx_http_script_regex_code_t *) e->ip; r = e->request; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http script regex: \"%V\"", &code->name); if (code->uri) { e->line = r->uri; } else { e->sp--; e->line.len = e->sp->len; e->line.data = e->sp->data; } rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures); if (rc == NGX_REGEX_NO_MATCHED) { if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "\"%V\" does not match \"%V\"", &code->name, &e->line); } e->ncaptures = 0; if (code->test) { if (code->negative_test) { e->sp->len = 1; e->sp->data = (u_char *) "1"; } else { e->sp->len = 0; e->sp->data = (u_char *) ""; } e->sp++; e->ip += sizeof(ngx_http_script_regex_code_t); return; } e->ip += code->next; return; } if (rc < 0) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", rc, &e->line, &code->name); e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "\"%V\" matches \"%V\"", &code->name, &e->line); } e->ncaptures = code->ncaptures; if (code->test) { if (code->negative_test) { e->sp->len = 0; e->sp->data = (u_char *) ""; } else { e->sp->len = 1; e->sp->data = (u_char *) "1"; } e->sp++; e->ip += sizeof(ngx_http_script_regex_code_t); return; } if (code->status) { e->status = code->status; if (!code->redirect) { e->ip = ngx_http_script_exit; return; } } if (code->uri) { r->internal = 1; r->valid_unparsed_uri = 0; if (code->break_cycle) { r->valid_location = 0; r->uri_changed = 0; } else { r->uri_changed = 1; } } if (code->lengths == NULL) { e->buf.len = code->size; if (code->uri) { if (rc && (r->quoted_uri || r->plus_in_uri)) { e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_ARGS); } } for (n = 1; n < (ngx_uint_t) rc; n++) { e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n]; } } else { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); le.ip = code->lengths->elts; le.request = r; le.captures = e->captures; le.ncaptures = e->ncaptures; len = 1; /* reserve 1 byte for possible "?" */ while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; len += lcode(&le); } e->buf.len = len; } if (code->add_args && r->args.len) { e->buf.len += r->args.len + 1; } e->buf.data = ngx_palloc(r->pool, e->buf.len); if (e->buf.data == NULL) { e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } e->quote = code->redirect; e->pos = e->buf.data; e->ip += sizeof(ngx_http_script_regex_code_t); } void ngx_http_script_regex_end_code(ngx_http_script_engine_t *e) { u_char *dst, *src; ngx_http_request_t *r; ngx_http_script_regex_end_code_t *code; code = (ngx_http_script_regex_end_code_t *) e->ip; r = e->request; e->quote = 0; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http script regex end"); if (code->redirect) { dst = e->buf.data; src = e->buf.data; ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, NGX_UNESCAPE_URI); if (src < e->pos) { dst = ngx_copy(dst, src, e->pos - src); } e->pos = dst; if (code->add_args && r->args.len) { *e->pos++ = (u_char) (code->args ? '&' : '?'); e->pos = ngx_copy(e->pos, r->args.data, r->args.len); } e->buf.len = e->pos - e->buf.data; if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "rewritten redirect: \"%V\"", &e->buf); } r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } r->headers_out.location->hash = 1; r->headers_out.location->key.len = sizeof("Location") - 1; r->headers_out.location->key.data = (u_char *) "Location"; r->headers_out.location->value = e->buf; e->ip += sizeof(ngx_http_script_regex_end_code_t); return; } if (e->args) { e->buf.len = e->args - e->buf.data; if (code->add_args && r->args.len) { *e->pos++ = '&'; e->pos = ngx_copy(e->pos, r->args.data, r->args.len); } r->args.len = e->pos - e->args; r->args.data = e->args; e->args = NULL; } else { e->buf.len = e->pos - e->buf.data; } if (e->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "rewritten data: \"%V\", args: \"%V\"", &e->buf, &r->args); } if (code->uri) { r->uri = e->buf; if (r->uri.len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "the rewritten URI has a zero length"); e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } if (ngx_http_set_exten(r) != NGX_OK) { e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } } e->ip += sizeof(ngx_http_script_regex_end_code_t); } #endif void ngx_http_script_return_code(ngx_http_script_engine_t *e) { ngx_http_script_return_code_t *code; code = (ngx_http_script_return_code_t *) e->ip; e->status = code->status; e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t); } void ngx_http_script_break_code(ngx_http_script_engine_t *e) { e->request->uri_changed = 0; e->ip = ngx_http_script_exit; } void ngx_http_script_if_code(ngx_http_script_engine_t *e) { ngx_http_script_if_code_t *code; code = (ngx_http_script_if_code_t *) e->ip; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script if"); e->sp--; if (e->sp->len && e->sp->data[0] != '0') { if (code->loc_conf) { e->request->loc_conf = code->loc_conf; ngx_http_update_location_config(e->request); } e->ip += sizeof(ngx_http_script_if_code_t); return; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script if: false"); e->ip += code->next; } void ngx_http_script_equal_code(ngx_http_script_engine_t *e) { ngx_http_variable_value_t *val, *res; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script equal"); e->sp--; val = e->sp; res = e->sp - 1; e->ip += sizeof(uintptr_t); if (val->len == res->len && ngx_strncmp(val->data, res->data, res->len) == 0) { *res = ngx_http_variable_true_value; return; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script equal: no"); *res = ngx_http_variable_null_value; } void ngx_http_script_not_equal_code(ngx_http_script_engine_t *e) { ngx_http_variable_value_t *val, *res; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script not equal"); e->sp--; val = e->sp; res = e->sp - 1; e->ip += sizeof(uintptr_t); if (val->len == res->len && ngx_strncmp(val->data, res->data, res->len) == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script not equal: no"); *res = ngx_http_variable_null_value; return; } *res = ngx_http_variable_true_value; } void ngx_http_script_file_code(ngx_http_script_engine_t *e) { ngx_err_t err; ngx_file_info_t fi; ngx_http_variable_value_t *value; ngx_http_script_file_code_t *code; value = e->sp - 1; code = (ngx_http_script_file_code_t *) e->ip; e->ip += sizeof(ngx_http_script_file_code_t); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script file op %p", code->op); if (ngx_file_info(value->data, &fi) == -1) { err = ngx_errno; if (err != NGX_ENOENT && err != NGX_ENOTDIR) { ngx_log_error(NGX_LOG_CRIT, e->request->connection->log, err, ngx_file_info_n " \"%s\" failed", value->data); } switch (code->op) { case ngx_http_script_file_plain: goto false; case ngx_http_script_file_not_plain: goto true; } goto false; } switch (code->op) { case ngx_http_script_file_plain: if (ngx_is_file(&fi)) { goto true; } goto false; case ngx_http_script_file_not_plain: if (ngx_is_file(&fi)) { goto false; } goto true; } false: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script file op false"); *value = ngx_http_variable_null_value; return; true: *value = ngx_http_variable_true_value; return; } void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e) { size_t len; ngx_http_script_engine_t le; ngx_http_script_len_code_pt lcode; ngx_http_script_complex_value_code_t *code; code = (ngx_http_script_complex_value_code_t *) e->ip; e->ip += sizeof(ngx_http_script_complex_value_code_t); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script complex value"); ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); le.ip = code->lengths->elts; le.request = e->request; le.captures = e->captures; le.ncaptures = e->ncaptures; for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } e->buf.len = len; e->buf.data = ngx_palloc(e->request->pool, len); if (e->buf.data == NULL) { e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; } e->pos = e->buf.data; e->sp->len = e->buf.len; e->sp->data = e->buf.data; e->sp++; } void ngx_http_script_value_code(ngx_http_script_engine_t *e) { ngx_http_script_value_code_t *code; code = (ngx_http_script_value_code_t *) e->ip; e->ip += sizeof(ngx_http_script_value_code_t); e->sp->len = code->text_len; e->sp->data = (u_char *) code->text_data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script value: \"%V\"", e->sp); e->sp++; } void ngx_http_script_set_var_code(ngx_http_script_engine_t *e) { ngx_http_request_t *r; ngx_http_script_var_code_t *code; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script set var"); code = (ngx_http_script_var_code_t *) e->ip; e->ip += sizeof(ngx_http_script_var_code_t); r = e->request; e->sp--; r->variables[code->index].len = e->sp->len; r->variables[code->index].valid = 1; r->variables[code->index].no_cachable = 0; r->variables[code->index].not_found = 0; r->variables[code->index].data = e->sp->data; } void ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e) { ngx_http_script_var_handler_code_t *code; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script set var handler"); code = (ngx_http_script_var_handler_code_t *) e->ip; e->ip += sizeof(ngx_http_script_var_handler_code_t); e->sp--; code->handler(e->request, e->sp, code->data); } void ngx_http_script_var_code(ngx_http_script_engine_t *e) { ngx_http_variable_value_t *value; ngx_http_script_var_code_t *code; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script var"); code = (ngx_http_script_var_code_t *) e->ip; e->ip += sizeof(ngx_http_script_var_code_t); value = ngx_http_get_flushed_variable(e->request, code->index); if (value && !value->not_found) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script var: \"%V\"", value); *e->sp = *value; e->sp++; return; } *e->sp = ngx_http_variable_null_value; e->sp++; } void ngx_http_script_nop_code(ngx_http_script_engine_t *e) { e->ip += sizeof(uintptr_t); }