Nginx系列(十三):变量机制

1. 内部变量:
  • preconfiguration阶段,调用ngx_http_variables_add_core_vars:
    1)初始化cmcf->variables_keys结构体;
    2)遍历ngx_http_core_variables核心变量数组,创建ngx_http_variable_t结构体作为value,变量名为key加入cmcf->variables_keys->keys数组,同时根据核心变量数组成员,为ngx_http_variable_t的其它成员,如set_handler、get_handler等赋值。

  • HTTP各模块配置解析阶段:
    1)对于各模块中使用到的变量,如rewrite模块的set或rewrite指令,调用ngx_http_get_variable_index函数,创建ngx_http_variable_t结构体,加入cmcf->variables数组,此时结构体除name、index外的其他成员均未赋值。

  • HTTP各模块配置解析结束阶段(ngx_http_block->ngx_http_variables_init_vars):
    1)变量cmcf->variables和cmcf->variables_keys->keys数组,对于两数组中都存在的成员进行关联,为前者赋值get_handler,为后者赋值index。
    2)创建变量hash表。

2. 外部变量:
  • REWRITE模块配置解析阶段:
    1)调用ngx_http_add_variable将变量加入cmcf->variables_keys->keys数组。
    2)调用ngx_http_get_variable_index将变量加入cmcf->variables数组,获取index。
    3)lcf->codes加入函数指针,用于将变量的实际值保存在栈中。
    4)如果set的变量为内部变量,则lcf->codes加入函数指针,通过调用v->set_handler获得栈中变量值;如果set的变量为外部变量,则则lcf->codes加入函数指针(ngx_http_script_set_var_code),将栈中的变量值写入r->variables[]。

  • cmcf->variables_keys(ngx_hash_keys_arrays_t结构体)
    cmcf->variables_keys->keys_hash:二维数组,一维代表name算出的hash,二维代表该hash下的所有name节点,该数组用于快速检索name是否存在冲突。
    cmcf->variables_keys->keys:一维数组,节点包含name、key、value。

3. 变量获取
struct ngx_http_variable_s {
    ngx_str_t                     name;   /* must be first to build the hash */
    ngx_http_set_variable_pt      set_handler;
    ngx_http_get_variable_pt      get_handler;
    uintptr_t                     data;
    ngx_uint_t                    flags;
    ngx_uint_t                    index;
};
  • get_handler:提供获取该变量值的方法,在业务阶段调用。
  • set_handler:对于被重写的内部变量,在脚本执行(rewrite)阶段,通过该方法对变量值进行设置。
  • flags :
    //变量可被重写
    #define NGX_HTTP_VAR_CHANGEABLE 1
    //每次使用都需要通过get_handler重新获取,不可再请求中缓存
    #define NGX_HTTP_VAR_NOCACHEABLE 2
    //存在于cmcf->variables
    #define NGX_HTTP_VAR_INDEXED 4
    //该变量不加入hash表,即业务无法通过变量名获取变量值,只能通过index
    #define NGX_HTTP_VAR_NOHASH 8
    //不通过get函数获取值
    #define NGX_HTTP_VAR_WEAK 16
    //前缀型变量
    #define NGX_HTTP_VAR_PREFIX 32
  • index:在cmcf->variables中的编号

请求到来时,初始化

  r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
                                        * sizeof(ngx_http_variable_value_t));

该数组用于保存变量的缓存值。
调用

   if (v[index].get_handler(r, &r->variables[index], v[index].data)
        == NGX_OK)

对该请求某变量值进行获取,并在r->variables[index]缓存。

typedef struct {
    unsigned    len:28;
 
    unsigned    valid:1;
    unsigned    no_cacheable:1;
    unsigned    not_found:1;
    unsigned    escape:1;
 
    u_char     *data;
} ngx_variable_value_t;

获取变量值的接口
ngx_http_get_indexed_variable 通过index获取变量值,可能获取到r中的缓存
ngx_http_get_flushed_variable 通过index获取变量值,不获取缓存,重新调用get_handler
ngx_http_get_variable 通过变量名获取变量值,会查询hash表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值