关于nginx模块注册阶段问题

43 views
Skip to first unread message

小获

unread,
Jun 1, 2012, 5:20:42 AM6/1/12
to openresty
现在有一个需求,需要对http请求头信息进行处理(该处理通过一个模块执行自定义函数),然后在配置文件中根据处理结果进行不同配置。
如:
location /test {
my_module_func;
if (my_module_fun_result) { # 模块返回结果 true/false
# additional config here
}
}
请问,这样需求的模块该如何实现,模块应该注册到哪个阶段?

agentzh

unread,
Jun 1, 2012, 5:42:58 AM6/1/12
to open...@googlegroups.com
Hello!

2012/6/1 小获 <huang...@gmail.com>:

从你给的用法看,只能注册在 rewrite 阶段了。。。另外,my_module_fun_result 应该是一个 nginx 变量吧?

Regards,
-agentzh

huangfxbupt

unread,
Jun 1, 2012, 5:47:46 AM6/1/12
to openresty
my_module_fun_result是一个变量。
注册到rewrite阶段,能保证location/test 中的执行顺序是 my_module_func -> if(my_module_fun_result),并且在if(...) 时my_module_fun_result已是模块中的赋值?
新手,非常感谢~~
 

huangfxbupt
 
发件人: agentzh
发送时间: 2012-06-01 17:42
收件人: openresty
主题: Re: [openresty] 关于nginx模块注册阶段问题
-- 
邮件自: 列表“openresty”,专用于技术讨论!
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com

agentzh

unread,
Jun 1, 2012, 6:03:23 AM6/1/12
to open...@googlegroups.com
Hello!

2012/6/1 huangfxbupt <huang...@gmail.com>:


> my_module_fun_result是一个变量。
> 注册到rewrite阶段,能保证location/test 中的执行顺序是 my_module_func ->
> if(my_module_fun_result),并且在if(...) 时my_module_fun_result已是模块中的赋值?
> 新手,非常感谢~~
>

用户注册在 rewrite 阶段的模块如自己不做特殊处理,都会运行在标准的 ngx_rewrite 模块之前(而 if 配置指令是
ngx_rewrite 模块提供的)。

考虑到:

1. ngx_rewrite 模块运行在 rewrite 阶段,所以你的模块必须运行在 rewrite 阶段之前(含 rewrite 阶段)。

2. 同时由于你又需要在 location 配置块中进行开关,所以你的模块的运行阶段须在 find-config 阶段之后。

综合 1 与 2,再加上 find-config 阶段之后紧接着的便是 rewrite 阶段,所以 rewrite 阶段是唯一选择。

关于请求处理阶段的更多信息,可以参见我的 nginx 连载教程:

http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.html#02-NginxDirectiveExecOrder01

Regards,
-agentzh

huangfxbupt

unread,
Jun 4, 2012, 2:48:13 AM6/4/12
to openresty
发现还是有问题:我的my_module_func需要对http请求头进行处理,是不是意味着my_module_func无法在rewrite阶段执行?rewrite的handler没有ngx_http_request_t* 变量。
 
我要实现的需求:模块执行一个函数操作http请求头,将函数的结果记录到一个变量,然后在配置文件的rewrite阶段使用。可以实现吗?
需求来源:需要在配置文件中根据模块的执行结果进行不同的配置。(这样的需求应该还是比较普通的吧?)
 
我的一个已有实现思路:写一个处理模块对http请求头进行操作,根据操作结果调用ngx_http_finalize_request(r, result_code),然后在配置文件中用error_page将不同的result_code重定向到对应的location。如下所示:

location /xxxxx {

cmd xxx;

# xxxxxx  

error_page 420 = @yes_xx;

error_page 421 = @no_xx;

}

Location @yes_xx {

internal;

# add config here

}

Location @not_xx {

internal;

# add config here

}

 
这样可以实现功能,但感觉配置文件有点繁琐,而且会不会有效率问题或者跳转带来的其它问题?
 
非常感谢~~~
 
祝好!
 

huangfxbupt
 
发件人: agentzh
发送时间: 2012-06-01 18:03
收件人: openresty
主题: Re: Re: [openresty] 关于nginx模块注册阶段问题

agentzh

unread,
Jun 4, 2012, 3:09:24 AM6/4/12
to open...@googlegroups.com
Hello!

2012/6/4 huangfxbupt <huang...@gmail.com>:
> 发现还是有问题:我的my_module_func需要对http请求头进行处理,是不是意味着my_module_func无法在rewrite阶段执行?

我的 ngx_headers_more 模块正是在 rewrite 阶段注册的 handler 中对请求头进行修改的:

http://wiki.nginx.org/HttpHeadersMoreModule

可以参考这个模块的实现代码。

我不明白你的结论从何而来。

> rewrite的handler没有ngx_http_request_t*
> 变量。

rewrite 阶段的 handler 是有 ngx_http_request_t *r 参数的,例如

static ngx_int_t
ngx_http_rewrite_handler(ngx_http_request_t *r)
{
...
}

可以参见标准的 ngx_rewrite 模块的实现代码。

>
> 我要实现的需求:模块执行一个函数操作http请求头,将函数的结果记录到一个变量,然后在配置文件的rewrite阶段使用。可以实现吗?

当然。

> 需求来源:需要在配置文件中根据模块的执行结果进行不同的配置。(这样的需求应该还是比较普通的吧?)
>
> 我的一个已有实现思路:写一个处理模块对http请求头进行操作,根据操作结果调用ngx_http_finalize_request(r,
> result_code),然后在配置文件中用error_page将不同的result_code重定向到对应的location。如下所示:
>

这里完全没必要通过滥用 error_page 机制来实现。Nginx 的内部跳转正是为这个目的而生的,况且 error_page
的底层实现也是基于 Nginx 的内部跳转功能。可以参考下面这个例子:

http://openresty.org/#RoutingMySQLQueriesBasedOnURIArgs

>
> 这样可以实现功能,但感觉配置文件有点繁琐,而且会不会有效率问题或者跳转带来的其它问题?
>

我感觉你需要的功能完全可以通过 ngx_lua 模块来实现:

http://wiki.nginx.org/HttpLuaModule

或许并没有必要自己写一个 Nginx C 模块?

仅供参考。

Regards,
-agentzh

Reply all
Reply to author
Forward
0 new messages