首先 看看完整的源码
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>
static char *set(ngx_conf_t *, ngx_command_t *, void *);
static ngx_int_t handler(ngx_http_request_t *);
static ngx_command_t test_commands[] = {
{
ngx_string("hello_world"),
NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
set,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL
},
ngx_null_command
};
//这里没有什么需要进行配置的之后在讲解
static ngx_http_module_t test_ctx = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
ngx_module_t ngx_http_test_module = {
NGX_MODULE_V1,//定义module版本
&test_ctx,//module context
test_commands,//commands
NGX_HTTP_MODULE,//定义是http_module
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NGX_MODULE_V1_PADDING
};
static char *set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
ngx_http_core_loc_conf_t *corecf;
corecf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
corecf->handler = handler;
return NGX_CONF_OK;
};
static ngx_int_t handler(ngx_http_request_t *req) {
// 响应内容
u_char html[1024] = "<h1>hello world, foorbar!!!</h1>";
//返回状态码
req->headers_out.status = 200;
int len = sizeof(html) - 1;
//content_length
req->headers_out.content_length_n = len;
//content_type
ngx_str_set(&req->headers_out.content_type, "text/html");
//先发送header
ngx_http_send_header(req);
ngx_buf_t *b;
b = ngx_pcalloc(req->pool, sizeof(ngx_buf_t));
ngx_chain_t out;
out.buf = b;
out.next = NULL;
b->pos = html;
b->last = html + len;
b->memory = 1;
b->last_buf = 1;
//发送http包体
return ngx_http_output_filter(req, &out);
}
ngx_command_t解析
首先来解析ngx_command_t
这个结构体
static ngx_command_t ngx_http_mirror_commands[] = {
{ ngx_string("hello_world"), //定义名称
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,//定义改配置出现的位置
set,//配置handler
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL }
第一行ngx_string("hello_world")
这个定义了名称,只要配置文件中出现了该配置项,就能够启用该模块,比如下面这样的模式
location /hello_world {
hello_world;
}
第二行NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1
定义了出现的位置
分别代表了可以出现在main{}、server{}和location{}。NGX_CONF_TAKE1:
配置指令接受1个参数。
第三行set
static char *set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
//配处理的handler
ngx_http_core_loc_conf_t *corecf;
corecf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
//这块是处理用户请求到NGX_HTTP_CONTENT_PHASE这个阶段的时候
corecf->handler = handler;
return NGX_CONF_OK;
};
下面是请求的各个处理阶段,咱们的hello_world模块是属于NGX_HTTP_CONTENT_PHASE处理阶段
typedef enum {
//接受到头部的阶段
NGX_HTTP_POST_READ_PHASE = 0,
//在还没有查询到URL匹配的location前,这时rewrite重写URL也作为一个独立的HTTP阶段
NGX_HTTP_SERVER_REWRITE_PHASE,
//根据url寻找匹配的location,这个阶段通常由ngx_http_core_module模块实现,
NGX_HTTP_FIND_CONFIG_PHASE,
//这个是NGX_HTTP_FIND_CONFIG_PHASE之后的阶段,Location请求地址重写阶段
NGX_HTTP_REWRITE_PHASE,
//这一阶段是用于在rewrite重写URL后重写跳转到NGX_HTTP_FIND_CONFIG_PHASE的阶段
NGX_HTTP_POST_REWRITE_PHASE,
//http模块可以介入处理的阶段
NGX_HTTP_PREACCESS_PHASE,
//这个阶段用于让HTTP模块判断是否允许这个请求访问Nginx服务器
NGX_HTTP_ACCESS_PHASE,
//这个阶段将负责构造拒绝服务的用户响应
NGX_HTTP_POST_ACCESS_PHASE,
//content的预处理阶段
NGX_HTTP_PRECONTENT_PHASE,
//用于处理HTTP请求内容的阶段,
NGX_HTTP_CONTENT_PHASE,
//处理完请求后记录日志的阶段,
NGX_HTTP_LOG_PHASE
} ngx_http_phases;