|零基础开发 nginx 模块( 五 )
static ngx_command_t ngx_http_hello_commands[] = { { ngx_string(''hello''), NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1, hello, NGX_HTTP_MAIN_CONF_OFFSET, 0, NULL }, ngx_null_command };编写指令处理函数
指令执行处理:
- nginx 根据指令 type 字段设置的特性自动校验指令位置 , 参数个数等信息 , 并将指令语句解析为字符串数组 (类似 shell 命令行), 保存到 cf->args, 再调用指令处理函数 。
- 指令处理函数执行成功时返回 NGX_CONF_OK, 发生错误时返回错误消息 。
- 为了简化和统一指令处理 ,nginx 预定义了许多标准指令处理函数 , 如 ngx_conf_set_str_slot() 将一个字符串参数解析保存为一个 ngx_str_t 配置项 。
- hello 指令可复用 ngx_conf_set_str_slot() 函数获取参数值 , 再添加额外逻辑打印 hello 语句 。
static char* hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *str = conf; char *rv; rv = ngx_conf_set_str_slot(cf, cmd, str); if (rv != NGX_CONF_OK) { return rv; } ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, ''HELLO %V'', str); return NGX_CONF_OK; }
- ngx_log_error() 是一个宏 , 最终将调用 ngx_log_error_core() 函数 。
- ngx_log_error() 第 3 个参数 err 表示系统错误码 , 无对应错误码时使用 0。
- nginx 未使用 C 标准库的 snprintf() 字符串格式化函数 , 而是自己实现了 ngx_snprintf() 函数 , 并自定义了类似的格式化字符串 , 其中 %V 表示输出 ngx_str_t * 指针指向的字符串 。
在配置文件 objs/nginx.conf http 配置下添加如下配置:
hello Nginx;在 nginx 代码仓库目录下执行如下命令 , nginx 日志将输出 ''HELLO Nginx'' 语句 , 按 Ctrl-C 退出 nginx。
objs/nginx -p ''$PWD'' -c objs/nginx.confHTTP 请求处理器
nginx 定义了多个 HTTP 请求处理阶段 (phase), 如读取完 HTTP 请求头后即进入 NGX_HTTP_POST_READ_PHASE 阶段 。 可在 HTTP 请求处理的各个阶段添加处理器函数 , 类似于 Java Servlet 中的 HTTP 过滤器 (Filter)。
HTTP 处理器函数签名 (函数类型) 如下:
typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
- 参数 r 为 HTTP 请求结构体 。
- 返回值为 NGX_DECLINED 时 , 表示继续执行下一个处理器 。
- 发生错误时 , 返回 HTTP 错误码 , 如服务器错误 500 NGX_HTTP_INTERNAL_SERVER_ERROR, nginx 将立即返回请求 。
static ngx_int_t hello_handler(ngx_http_request_t *r) { ngx_str_t * str = ngx_http_get_module_main_conf(r, ngx_http_hello_module); ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, ''HELLO %V, uri: %V'', str, &r->uri); return NGX_DECLINED; }为 HTTP 模块编写一个 postconfiguration 函数 hello_init(), 将 HTTP 处理器 hello_handler() 注册到 NGX_HTTP_POST_READ_PHASE 阶段 。 nginx 将在完成配置解析 (执行完配置指令) 后执行 HTTP 模块的 postconfiguration 函数 , 以完成模块初始化 。
static ngx_int_t hello_init(ngx_conf_t *cf) { ngx_http_handler_pt*h; ngx_http_core_main_conf_t*cmcf; cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); if (h == NULL) { return NGX_ERROR; } *h = hello_handler; return NGX_OK; }更新 ngx_http_module_t ngx_http_hello_module_ctx, 设置 postconfiguration 为 hello_init() 函数 。
推荐阅读
- |万向肖风:区块链的商业突破不是从 C 端开始,而是从开发者开始
- 华为开发者联盟|华为课堂|华为帐号如何保护您的帐号安全?
- 品谷农产品|专业的软件开发流程,应该是怎样的呢?
- AI人工智能|“眼健康黑科技” AI智能眼科检测仪来了!展锐虎贲T710开发板等你来盘!
- 智慧医疗|“眼健康黑科技” AI智能眼科检测仪来了!展锐虎贲T710开发板等你来盘!
- 智能电视|苹果正在开发带有A12x和A14x芯片的Apple TV
- IBM|百年IBM再度迎来历史性变革 拆分基础设施服务部门全力押宝云计算
- 互联网分析师于斌|鸿蒙搜索和EMUI11!华为开发者大会回顾
- cnBeta|前苹果工程师/自动修正创造者开发首款App:名为Up Spell的文字游戏
- 化学奖|女科学家获2020年诺贝尔化学奖,她们开发了“基因剪刀”
