完成与后端服务器的交互
难以置信!有这么多的功能任你处置,而你只需仅仅通过多组有用的钩子(由函数指针组成的结构体)和相应的实现函数。让我们开始接触一些模块吧。 3. Nginx模块的组成 我说过,Nginx模块的构建是很灵活的。这一节讲描述的东西会经常出现。它可以帮助你理解模块,也可以作为开发模块的手册。 3.1. 模块配置Struct(s) 模块的配置struct有三种,分别是main,server和location。绝大多数模块仅需要一个location配置。名称约定如下:ngx_http_<module name>_(main|srv|loc)_conf_t. 这里有一个dav模块中的例子: typedefstruct{ngx_uint_t methods;
ngx_flag_t create_full_put_path;
ngx_uint_t access;
} ngx_http_dav_loc_conf_t; 注意到上面展示了Nginx的一些特殊类型:(ngx_uint_t 和 ngx_flag_t); 这些只是基本类型的别名而已。(如果想知道具体是什么的别名,可以参考 ). 这些类型用在配置结构体中的情形很多。 3.2. 模块指令 模块的指令是定义在一个叫做ngx_command_t的静态数组中的。下面举个我自己写的小模块中的例子,来告诉你模块指令是如何声明的: static ngx_command_t ngx_http_circle_gif_commands[]={
{ ngx_string("circle_gif"),
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
ngx_http_circle_gif,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
{ ngx_string("circle_gif_min_radius"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_circle_gif_loc_conf_t, min_radius),
NULL },
...
ngx_null_command
}; 下面是结构体ngx_command_t(静态数组里的每一个元素)的定义 , 你可以在 找到它: struct ngx_command_t {
ngx_str_t name;
ngx_uint_t type;
char*(*set)(ngx_conf_t *cf, ngx_command_t *cmd,void*conf);
ngx_uint_t conf;
ngx_uint_t offset;
void*post;
}; 结构体成员是多了点,不过各司其职,都有用处。分别来看: 结构体成员 name 是指令的字符串(顾名思义就是指令名称),不能包含空格. 它的类型是ngx_str_t, 通常都是以像(e.g.) ngx_str("proxy_pass")这样的方式来实例化. 注意: ngx_str_t 包含一个存放字符串内容的data字段,和一个存放字符串长度的len字段。Nginx广泛地使用这个类型来存放字符串。 结构体成员type是标识的集合,表明这个指令在哪里出现是合法的、指令的参数有几个。应用中,标识一般是下面多个值的BIT或:
NGX_HTTP_MAIN_CONF: 指令出现在main配置部分是合法的
NGX_HTTP_SRV_CONF: 指令在server配置部分出现是合法的 config
NGX_HTTP_LOC_CONF: 指令在location配置部分出现是合法的
NGX_HTTP_UPS_CONF: 指令在upstream配置部分出现是合法的
NGX_CONF_NOARGS: 指令没有参数
NGX_CONF_TAKE1: 指令读入1个参数
NGX_CONF_TAKE2: 指令读入2个参数
...
NGX_CONF_TAKE7: 指令读入7个参数
NGX_CONF_FLAG: 指令读入1个布尔型数据 ("on" or "off")
NGX_CONF_1MORE: 指令至少读入1个参数