nginx 变量解析

来源:互联网 发布:mac 电视直播 编辑:程序博客网 时间:2024/05/16 08:22
   #nginx.conf     location /bar {         set_form_input_multi $xl_foo xl_data; # read all "data" field into $foo         array_join ' ' $xl_data; # now $data is a string         array_join ' ' $xl_foo;  # now $foo is a string    }
以此举例:
首先进入
ngx_http_set_form_input_conf_handler进行相应的变量初始化,其中分为几个步骤
1  ndk_set_var_name 方法调用ngx_http_add_variable增加变量$xl_foo从而获取相应的index变量索引
2  ndk_http_rewrite_value 方法将xl_data进行压栈如下
     val = ngx_http_script_start_code(cf->pool, &lcf->codes,                                         sizeof(ngx_http_script_value_code_t));
        val->code = ngx_http_script_value_code;        val->value = (uintptr_t) n;        val->text_len = (uintptr_t) value->len;        val->text_data = (uintptr_t) value->data;
表示压入一个元素val,值为xl_data该字符串,记住这是第一个压栈数据,ngx_http_script_start_code弹出栈的操作如下:
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++;}

3 ndk_set_var_filter 设置回调filter执行,又一个压栈操作
        svsd = ngx_http_script_start_code(cf->pool, &rlcf->codes,                                          sizeof(ndk_set_var_size_data_code_t));        if (svsd == NULL) {            return NGX_CONF_ERROR;        }        svsd->code = ndk_set_var_multi_value_data_code;        svsd->func = filter->func;        svsd->size = filter->size;        svsd->data = filter->data;        ndk_set_variable_value_space(rlcf, svsd->size);        break;
弹出栈的操作为
static voidndk_set_var_multi_value_data_code(ngx_http_script_engine_t *e){    ngx_int_t                        rc;    ngx_str_t                        str;    ngx_http_variable_value_t       *v;    ndk_set_var_size_data_code_t    *svsd;    ndk_set_var_value_data_pt        func;    svsd = (ndk_set_var_size_data_code_t *) e->ip;    e->ip += sizeof(ndk_set_var_size_data_code_t);    v = e->sp - svsd->size;    e->sp = v + 1;    func = (ndk_set_var_value_data_pt) svsd->func;    rc = func(e->request, &str, v, svsd->data);    ndk_set_var_code_finalize(e, rc, v, &str);}
4 最后一部操作就是给xl_foo这个变量赋值
将会执行最后一个压栈操作
    vcode = ngx_http_script_start_code(cf->pool, &rlcf->codes,                                       sizeof(ngx_http_script_var_code_t));    if (vcode == NULL) {        return NGX_CONF_ERROR;    }    vcode->code = ngx_http_script_set_var_code;    vcode->index = (uintptr_t) info->index;

弹出栈的操作为:
ngx_http_script_set_var_code(ngx_http_script_engine_t *e){    ngx_http_request_t          *r;    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);    r = e->request;    e->sp--;    r->variables[code->index].len = e->sp->len;    r->variables[code->index].valid = 1;    r->variables[code->index].no_cacheable = 0;    r->variables[code->index].not_found = 0;    r->variables[code->index].data = e->sp->data;

以上4部分就是处理过程,最后利用ngx_http_rewrite_handler,
逐步执行弹出栈的操作
    e->sp = ngx_pcalloc(r->pool,                        rlcf->stack_size * sizeof(ngx_http_variable_value_t));    if (e->sp == NULL) {        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    e->ip = rlcf->codes->elts;    e->request = r;    e->quote = 1;    e->log = rlcf->log;    e->status = NGX_DECLINED;    while (*(uintptr_t *) e->ip) {        code = *(ngx_http_script_code_pt *) e->ip;        code(e);    }
从上到下依次执行
                                             
0 0