nginx 编写简单HTTP模块 hello world
来源:互联网 发布:广场舞制作软件 编辑:程序博客网 时间:2024/05/29 02:53
1. 编写HTTP模块
1.1 目标
- 编写一个简单的显示hello world 信息的HTTP 模块
1.2 几个重要组成部分
1.2.1 ngx_command_t 数组
也就是说, 对于我们在nginx.conf 中编写的配置项 mytest 来说, nginx 首先会遍历所有的模块(modules),而对于每个模块, 会遍历他所对应的ngx_command_t 数组, 试图找到关于我们的配置项mytest 的解析方式。
我们的这部分代码如下:
static ngx_command_t ngx_http_mytest_commands[] ={ { ngx_string("mytest"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, ngx_http_mytest, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command};
1.2.2 command中用于处理配置项参数的set 方法
static char *ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ ngx_http_core_loc_conf_t *clcf; //首先找到mytest配置项所属的配置块,clcf貌似是location块内的数据//结构,其实不然,它可以是main、srv或者loc级别配置项,也就是说在每个//http{}和server{}内也都有一个ngx_http_core_loc_conf_t结构体 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); //http框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段时,如果//请求的主机域名、URI与mytest配置项所在的配置块相匹配,就将调用我们//实现的ngx_http_mytest_handler方法处理这个请求 clcf->handler = ngx_http_mytest_handler; return NGX_CONF_OK;}
关于ngx_http_conf_get_module_loc_conf 的定义可以参考:
http://lxr.nginx.org/source/src/http/ngx_http_config.h#0065
本质: 就是设置ngx_http_mytest_handler, 匹配项被选中的时候, 应该如何解析。
1.2.3 定义ngx_http_module_t 接口
这部分的代码, 是用于http框架的, 相当于http框架的回掉函数, 由于这里并不需要框架做任何操作。
static ngx_http_module_t ngx_http_mytest_module_ctx ={ NULL, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */};
1.2.4 定义mytest模块
书本上对ngx_module_t 模块的解析:
而实际上, 只需要简单的设置3个项目: ctx(指向模块的上下文), commands, type(模块类型)
ngx_module_t ngx_http_mytest_module ={ NGX_MODULE_V1, &ngx_http_mytest_module_ctx, /* module context */ ngx_http_mytest_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING};
这样, mytest 模块在编译的时候, 就可以被加入到ngx_modules的全局数组中了。
1.2.5 处理用户请求的hello world handler
我们这里需要定义配置项被匹配之后的处理方法, ngx_http_mytest_handler:
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r){ //必须是GET或者HEAD方法,否则返回405 Not Allowed 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有一个很方便的初始化宏//ngx_string,它可以把ngx_str_t的data和len成员都设置好 ngx_str_t type = ngx_string("text/plain"); //返回的包体内容 ngx_str_t response = ngx_string("Hello World!"); //设置返回状态码 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);}
自此, 一个简单的nginx 的hello world 模块编写完毕
2. 将自己的HTTP模块编译进Nginx
- 在编译的时候加入参数, –add-module=PATH
2.1 config 文件
ngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"
3. 配置nginx.conf
在相应的server 中添加下面的指令
location \hello{ mytest;}
4. 运行效果
0 0
- nginx 编写简单HTTP模块 hello world
- Nginx编写HTTP模块:第一个Nginx HTTP模块 “Hello World!”
- nginx HTTP模块的hello world
- Nginx编写HTTP模块:“Hello World”的第二种写法(HTTP模块介入阶段的2种方法)
- 编写一个简单的内核模块程序Hello World!
- 编写 Hello world 模块驱动
- 编写 Hello world 模块驱动
- 【Nginx】 hello模块的编写
- Nginx学习——Hello World模块
- Nginx的第一个模块-Hello World
- Nginx模块开发之hello world
- nginx模块开发0(hello world)
- Linux内核驱动模块编写(Hello,World)
- Linux内核驱动模块编写(Hello,World)
- 第一个模块,hello world 驱动编写
- 编写入门的linux模块(Hello World)
- linux内核hello world模块编写
- nginx的HTTP模块编写
- 火车站、汽车站乘车建议
- Scrapy的架构初探
- hibernate的WARN错误HHH000223问题解决
- Android Fragment 的使用
- Oracle Length 和 Lengthb 函数说明
- nginx 编写简单HTTP模块 hello world
- C++灵魂所在之---继承篇
- java命令行编译运行多个java文件
- what is muxing and demuxing
- C++Primer 第4章笔记整理及运算符优先级表
- MULE ESB 配置(三)
- 获取/使用偏好设置文件共有3种方式
- Android蓝牙BLE(二)--使用蓝牙主机
- php foreach用法和实例