#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);
}
从上到下依次执行