nginx 变量解析

本文详细介绍了nginx配置文件中变量解析的过程,通过`nginx.conf`中的`location`指令和`set_form_input_multi`示例,解析了变量初始化、压栈操作、回调函数设置以及最终变量赋值的步骤,揭示了nginx如何处理HTTP请求中的变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   #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 void
ndk_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);
    }

从上到下依次执行

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值