|零基础开发 nginx 模块( 二 )
在 nginx 代码仓库旁边新建一个名为 nginx-hello-module 的模块文件夹 , 创建一个 config 脚本文件和一个 C 语言源码文件 hello_module.c , 即得到一个最简单的模块示例 , 目录结构如下 。
nginx/# nginx 代码仓库 ├── auto/# nginx 构建脚本目录 └── src/# nginx 源码目录, 其他文件夹暂未列出 。nginx-hello-module/# 模块源码目录 ├── config# 模块配置脚本, shell 脚本 └── hello_module.c# 模块源码文件编写 config 配置脚本内容如下:
# vim: set ft=sh et: ngx_addon_name=ngx_http_hello_module ngx_module_type=HTTP ngx_module_name=''$ngx_addon_name'' ngx_module_srcs=''$ngx_addon_dir/hello_module.c'' . auto/module
- 插件名 ngx_addon_name 和模块名 ngx_module_name 设置为 ngx_http_hello_module。
- 模块类型 ngx_module_type 设置为 HTTP。
- 源码文件列表 ngx_module_srcs 设置为 $ngx_addon_dir/hello_module.c 。 注意: 源码路径必须添加 $ngx_addon_dir/ 前缀 , 构建脚本才能正确找到源码文件 。
- 语句 . auto/module 调用 nginx 提供的模块配置脚本 , 这条语句固定添加到 config 文件最后 。
在 nginx 代码仓库下执行如下命令 , 增加配置上述 nginx-hello-module 模块 。
auto/configure --add-dynamic-module=../nginx-hello-module/在 nginx 代码仓库下执行如下命令编译模块 。
make modules竟然编译成功了!得到动态模块文件 objs/ngx_http_hello_module.so。 但此时模块还不可用 (尝试加载此模块将报错) , 因为我们还没有写任何代码 。
一个空模块
我们知道 , 一个 C 程序的入口是 main() 函数 。 而一个 nginx 动态模块的入口是一个 ngx_module_t 对象 , 其结构定义如下 。
typedef struct ngx_module_sngx_module_t; struct ngx_module_s { /* 私有字段 ... ... */ void*ctx; ngx_command_t*commands; ngx_uint_ttype; ngx_int_t(*init_master)(ngx_log_t *log); ngx_int_t(*init_module)(ngx_cycle_t *cycle); ngx_int_t(*init_process)(ngx_cycle_t *cycle); ngx_int_t(*init_thread)(ngx_cycle_t *cycle); void(*exit_thread)(ngx_cycle_t *cycle); void(*exit_process)(ngx_cycle_t *cycle); void(*exit_master)(ngx_cycle_t *cycle); /* 扩展备用字段 ... ... */ };除去私有字段和扩展备用字段 , 用户相关的字段可分为 3 个部分:
- 模块类型 ngx_uint_t type 和模块类型特定的信息 void *ctx。 模块类型必须与 config 脚本配置的类型一致 , 本例即为 HTTP, 源码中用 NGX_HTTP_MODULE 表示 。
- 模块提供的指令列表 ngx_command_t *commands。 列表以 ngx_null_command 结尾 , 列表可以为空 (仅包含一个 ngx_null_command 结尾标记)。
- 其余为模块生命周期管理函数 , 可全部设置为 NULL。
#define NGX_HTTP_MODULE0x50545448/* ''HTTP'' */ typedef struct { ngx_int_t(*preconfiguration)(ngx_conf_t *cf); ngx_int_t(*postconfiguration)(ngx_conf_t *cf); void*(*create_main_conf)(ngx_conf_t *cf); char*(*init_main_conf)(ngx_conf_t *cf, void *conf); void*(*create_srv_conf)(ngx_conf_t *cf); char*(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); void*(*create_loc_conf)(ngx_conf_t *cf); char*(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); } ngx_http_module_t;下面来编写 hello_module.c 源码 , 为简单起见 , 首先开发一个空模块吧 。
推荐阅读
- |万向肖风:区块链的商业突破不是从 C 端开始,而是从开发者开始
- 华为开发者联盟|华为课堂|华为帐号如何保护您的帐号安全?
- 品谷农产品|专业的软件开发流程,应该是怎样的呢?
- AI人工智能|“眼健康黑科技” AI智能眼科检测仪来了!展锐虎贲T710开发板等你来盘!
- 智慧医疗|“眼健康黑科技” AI智能眼科检测仪来了!展锐虎贲T710开发板等你来盘!
- 智能电视|苹果正在开发带有A12x和A14x芯片的Apple TV
- IBM|百年IBM再度迎来历史性变革 拆分基础设施服务部门全力押宝云计算
- 互联网分析师于斌|鸿蒙搜索和EMUI11!华为开发者大会回顾
- cnBeta|前苹果工程师/自动修正创造者开发首款App:名为Up Spell的文字游戏
- 化学奖|女科学家获2020年诺贝尔化学奖,她们开发了“基因剪刀”
