此文的目的:只是为了让代码飞起来,不涉及原理
测试的nginx版本: nginx-1.10.2
先上nginx配置:
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
mytest;
}
}
}
步骤一:
我们下载nginx源码,解压后,在源码目录创建目录ngx_http_mytest_module,
并需要在此目录中创建两个文件config和ngx_http_mytest_module.c,如下图
步骤二:
编辑config文件,内容如下
ngx_addon_name=ngx_http_mytest_module
HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"
步骤三:
编辑ngx_http_mytest_module.c文件,代码如下
#include
#include
#include
//声明mytest模块的配置处理方法
static char* ngx_http_mytest(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
//
static ngx_http_module_t ngx_http_mytest_module_ctx = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
//定义mytest模块配置处理
static ngx_command_t ngx_http_mytest_commands[] = {
{
//配置项名称
ngx_string("mytest"),
//配置项类型,指令在location配置部分出现是合法的,且无参数
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
//出现了该配置项时,调用此方法处理配置项的参数
ngx_http_mytest,
//
NGX_HTTP_LOC_CONF_OFFSET,
//
0,
//
NULL
},
//ngx_null_command是一个空的ngx_command宏
ngx_null_command
};
//定义mytest模块
ngx_module_t ngx_http_mytest_module = {
NGX_MODULE_V1,
&ngx_http_mytest_module_ctx,
ngx_http_mytest_commands,
NGX_HTTP_MODULE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NGX_MODULE_V1_PADDING
};
//请求处理方法
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t* r)
{
if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
//丢弃请求中的包体
ngx_int_t rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
return rc;
}
//设置返回的返回的Content-Type
ngx_str_t type = ngx_string("text/plain");
//返回的包体内容
ngx_str_t response = ngx_string("hello world!\n");
//设置返回状态码
r->headers_out.status = NGX_HTTP_OK;
//设置Content-Length的长度
r->headers_out.content_length_n = response.len;
//设置Content-Type
r->headers_out.content_type = type;
//发送HTTP头
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
//构造ngx_buf_t结构体准备发送包体
ngx_buf_t* b;
b = ngx_create_temp_buf(r->pool, response.len);
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
//将hello world复制到ngx_buf_t指向的内存中
ngx_memcpy(b->pos, response.data, response.len);
//注意,一定要设置好last指针
b->last = b->pos + response.len;
//声明这是最后一块缓冲区
b->last_buf = 1;
//构造发送时的ngx_chain_t结构体
ngx_chain_t out;
//赋值ngx_buf_t
out.buf = b;
//设置next为NULL
out.next = NULL;
/*最后一步为发送包体,发送结束后HTTP框架会调用ngx_http_finalize_request方法结束请求*/
return ngx_http_output_filter(r, &out);
}
//定义mytest模块的配置处理方法
static char* ngx_http_mytest(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
{
ngx_http_core_loc_conf_t* clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_mytest_handler;
return NGX_CONF_OK;
}
编译nginx,指定安装目录和增加的模块,如果全程没报错,意味着编译成功
./configure --prefix=/usr/local/nginx-1.10.2 --add-module=./ngx_http_mytest_module
make
make install
测试配置,并运行,通过curl测试模块的可用性,curl -i "127.0.0.1/"
也可以通过浏览器访问。
如下图
最后:此文没有讲解原理,没有讲模块是怎么添加进去的,也没有讲模块是怎么运行的,只是为了跑起来。
推荐文章:http://www.evanmiller.org/nginx-modules-guide.html
推荐书籍:《深入理解Nginx:模块开发与架构解析》
原文出自:http://blog.csdn.net/daiyudong2020/article/details/53502829
end;