简单的http过滤模块
来源:互联网 发布:用java开发apk的步骤 编辑:程序博客网 时间:2024/05/21 08:47
http过滤模块仅处理服务器发往客户端的http响应,不处理客户端发往服务器的http请求。
过滤模块的调用顺序
过滤链表
在编译nginx源码时,已经定义了一个由所有http过滤模块组成的单链表(每个元素都是一个独立的c源码文件。这个文件会通过两个static指针指向下一个文件中的过滤方法)
typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);typedef ngx_int_t (*ngx_http_output_body_filter_pt)(ngx_http_request_t *r,ngx_chain_t *chain); //chain表示要发送的包体
http框架中定义的链表入口
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;extern ngx_http_body_header_filter_pt ngx_http_top_body_filter;
过滤链表的顺序
每个http过滤模块的初始化方法都会把自己加入到单链表的首部
大多数官方http过滤模块都会把初始化方法放到postconfiguration指针中
http过滤模块的开发步骤
- 确定源代码文件名称
- 在源代码所在目录创建config脚本文件,在执行configure时将该目录添加进去。HTTP_FILTER_MODULES,当使用多个源代码文件实现1个http过滤模块时,需要在NGX_ADDON_SRCS变量中添加其他源代码文件
- 定义过滤模块。
- 处理感兴趣的配置项。
- 实现初始化方法。初始化方法就是把本模块中处理http头部的ngx_http_output_header_filter_pt和处理http包体的ngx_http_output_body_filter_pt方法插入到过滤模块链表的首部
- 实现处理http头部的方法
- 实现处理http包体的方法
- 编译安装,修改nginx.conf文件并启动自定义过滤模块
http过滤模块的简单例子
在返回包体前加一段字符串 “[my fiter prefix]”
编写config文件
使用一个源文件实现此功能,源文件名为:ngx_http_myfilter_module.c
在该文件所在目录添加config文件:
ngx_addon_name=ngx_http_myfilter_moduleHTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_myfilter_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_myfilter_module.c"
配置项和上下文
首先,希望在nginx.conf中有一个控制当前http过滤模块是否生效的配置项 参数为on | off。建立ngx_http_myfilter_conf_t结构体来存储配置项,使用ngx_flag_t类型的enable变量来存储这个参数值
typedef struct{ ngx_flag_t enable;}ngx_http_myfilter_conf_t;
下面的ngx_http_myfilter_create_conf用于分配存储配置项的结构体ngx_http_myfilter_conf_t;
static void* ngx_http_myfilter_create_conf(ngx_conf_t *cf){ ngx_http_myfilter_conf_t *mycf; //创建存储配置项的结构体 mycf=(ngx_http_myfilter_conf_t *)ngx_pcalloc(cf->pool,sizeof(ngx_http_myfilter_conf_t)); if(mycf==NULL){ return NULL; } //ngx_flat_t 类型的变量。如果使用预设函数ngx_conf_set_flag_slot解析配置项参数,那么必须初始化为NGX_CONF_UNSET mycf->enable=NGX_CONF_UNSET; return mycf;}
希望配置不止出现在location{…},还可以出现在server{…}或者http{…}
还需要实现一个配置项值得合并方法-ngx_http_myfilter_merge_conf
static char * ngx_http_myfilter_merge_conf(ngx_conf_t *cf,void *parent,void *child){ ngx_http_myfilter_conf_t *prev=(ngx_http_myfilter_conf_t*)parent; ngx_http_myfilter_conf_t *conf=(ngx_http_myfilter_conf_t*)child; //合并ngx_flat_t类型的配置项enable ngx_conf_merge_value(conf->enable,prev->enable,0); return NGX_CONF_OK;}
再建立一个http上下文结构体ngx_http_myfilter_ctx_t,其中包括add_prefix整型成员,表示是否添加前缀
typedef struct{ ngx_int_t add_prefix;}ngx_http_myfilter_ctx_t;
为0,表示不加;为1,表示加;为2,表示头已加过
HTTP头部处理方法在1个请求中只会被调用1次。但包体处理方法在1个请求中有可能被多次调用。
定义http过滤模块
定义模块前,需要先定义两个关键成员:ngx_command_t类型的commands数组和ngx_http_module_t类型的ctx 成员
定义ngx_http_myfilter_commands数组,处理配置项,将配置项解析到ngx_http_myfilter_conf_t上下文结构体的成员中
在定义ngx_http_module_t类型的ngx_http_myfilter_module_ctx时,需要将ngx_http_myfilter_create_conf回调方法放到create_loc_conf成员;中,ngx_http_myfilter_merge_conf回调方法则要放到merge_loc_conf成员中;
ngx_http_myfilter_init模块初始化方法放到postconfiguration。
有了ngx_command_t类型的commands数组和ngx_http_module_t类型的ctx之后,就可以定义ngx_http_myfilter_module过滤模块了
初始化http过滤模块
在定义ngx_http_myfilter_init方法时,首先需要定义静态指针ngx_http_next_header_filter,用于指向下一个过滤模块的http头部处理方法,定义静态指针ngx_http_next_body_filter,用于指向下一个过滤模块的http包体处理方法
处理请求中的http头部
处理请求的http包体
- 简单的http过滤模块
- Nginx开发一个简单的HTTP过滤模块
- Nginx开发一个简单的HTTP过滤模块
- Nginx模块开发(5)————开发简单的HTTP过滤模块
- 《深入理解Nginx》阅读与实践(四):简单的HTTP过滤模块
- 《深入理解Nginx》阅读与实践(四):简单的HTTP过滤模块
- nginx http模块 http过滤模块
- Nginx模块-简单的HTTP模块
- 开发一个HTTP过滤模块
- Nginx HTTP过滤模块开发
- 【Nginx】开发一个简单的HTTP模块
- nginx 开发简单的http模块
- Nginx学习笔记(八):HTTP过滤模块
- 【Nginx】开发一个HTTP过滤模块
- Nginx基础. 开发HTTP过滤模块
- nginx:将自己编写HTTP过滤模块融入nginx时遇到的问题
- 【Nginx】初识nginx---实现一个简单的http模块
- 深入理解nginx chap3 开发一个简单的HTTP模块
- chrome源码分析1:content模型
- 深入理解Spring AOP
- iOS - 摇一摇
- 康拓展开
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
- 简单的http过滤模块
- Android 高清加载巨图方案 拒绝压缩图片
- 实战Nginx与PHP(FastCGI)的安装、配置与优化
- java基础知识(标识符,命名规则,注释)
- Java四种生成xml文件的方法
- LeetCode 89. Gray Code(生成格雷码)
- 得到格式化的时间
- Android Studio NDk调试(基于gradle-experimental插件与LLDB)
- Codeforces 667D World Tour (最短路+枚举)