准备写成nginx核心模块开发实践教程
这篇博客对hello world模块程序(以下简称模块)解释。
1.模块源程序组成
模块源程序分2个文件,1个叫config,另1个叫ngx_core_hw.c。
其中config文件在编译时告诉nginx我们编写的模块的名称,去哪儿找我们写的这个模块的源程序来编译。
ngx_core_hw.c这个就是我们的hello world这个模块的源程序了。
2.config解释
没几行,直接在注释中进行解释了。
#ngx_core_hw_module是我们命名的hello world模块的名称
ngx_addon_name=ngx_core_hw_module
#下面一行将该模块添加到nginx的模块链的最后
CORE_MODULES="$CORE_MODULES ngx_core_hw_module"
#下面这行制定模块源程序的位置
#其中变量$ngx_addon_dir就是在./configure --add-module=../ngx_core_hello_world时
#指定的../ngx_core_hello_world这个目录
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_core_hw.c"
3.ngx_core_hw.c解释
一个nginx模块至少需要几个数据结构:
- 配置指令数据结构,类型是:ngx_command_t
- 模块上下文数据结构,核心模块的类型是:ngx_core_module_t
如果是http模块,其上下文数据结构的类型是:ngx_http_module_t - 模块本身的数据结构,其类型是: ngx_module_t
- 最后就是各种结构体里面的其他函数、结构等的实现,此处hello world
只需要一个实现,就是ngx_core_hw_enable_handler这个函数指针的实现
下面就是对该源程序的具体解释
//开发nginx的模块,至少需include此头文件:ngx_core.h。
#include <ngx_core.h>
//ngx_core_hw_enable_handler这个函数指针指向的是具体执行打印hello world的函数
//三个参数就是nginx规定的此类函数指针的参数
static char *ngx_core_hw_enable_handler(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
//声明数组ngx_core_hw_commands[],这个数组中的每一个元素都是ngx_command_t类型的
static ngx_command_t ngx_core_hw_commands[] = {
//hw意思是hello world
//下面这个大括号就是ngx_command_t的具体格式
//第一行,指定"ngx_core_hw_enable"为nginx.conf
//这个配置文件的命令,意思是遇到这个命令,nginx就会
//执行这个模块
//ngx_string是nginx定义的一种字符串,使用起来很方便
{ ngx_string("ngx_core_hw_enable"),
//NGX_MAIN_CONF意思是上述的配置指令只能出现在nginx.conf的顶级目录下面
//NGX_CONF_TAKE1意思是这个命令需要带一个参数,我们这个地方需要带的参数是on
NGX_MAIN_CONF|NGX_CONF_TAKE1,
//下面就是前述声明的函数指针,这个模块启动后就执行这个函数指针指向的函数
ngx_core_hw_enable_handler,
//下面的2个0,null都暂不管,这次用不上
0,
0,
NULL },
//这个ngx_null_command是一个空的ngx_command_t,里面全是null或0
ngx_null_command
};
//此表明这个模块是核心模块
//ngx_core_module_t就是nginx的核心模块定义的数据结构
//它的具体定义见大括号内的内容
//ngx_core_hw_module_ctx是hello world这个核心模块的上下文
static ngx_core_module_t ngx_core_hw_module_ctx = {
//nchw意思是ngx_core_hello_world
ngx_string("nchw"),
NULL,
NULL
};
//下面就是核心模块ngx_core_hw_module的定义
ngx_module_t ngx_core_hw_module = {
//下面这个NGX_MODULE_V1是nginx定义的一个宏
//定义了nginx模块定义的七个值
NGX_MODULE_V1,
//下面这个就是前面定义的上下文数据结构的指针
&ngx_core_hw_module_ctx, /* module context */
//下面这个就是前面定义的核心模块的命令
ngx_core_hw_commands, /* module directives */
//这个是模块种类:核心模块,和前面的模块上下文的数据结构
//是一一对应的
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
//下面这个也是nginx定义的一个宏,一般不用改
NGX_MODULE_V1_PADDING
};
//ngx_core_hw_enable_handler这个函数指针的具体实现
static char *ngx_core_hw_enable_handler(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
//ngx_str_t是nginx定义的字符串结构体
ngx_str_t *value;
//下面这个等式就取得了配置文件中的
//ngx_core_hw_enable on;的on或者off这个值
value = (ngx_str_t *)cf->args->elts;
//如果判断值是on,那就打印hello world,否则就啥也不干,直接运行nginx
if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
printf("hello world!\n");
}
return (char *)NGX_CONF_OK;
}