设为首页 收藏本站
查看: 793|回复: 0

[经验分享] nginx的http模块开发--一个验证url参数的例子

[复制链接]

尚未签到

发表于 2015-7-26 12:29:01 | 显示全部楼层 |阅读模式
  本文开发一个nginx http模块基本的开发步骤和前篇http://www.iyunv.com/yjf512/archive/2013/06/10/3130890.html 说的一样,按照开发的六个步骤写。

配置文件及功能
  该模块的功能是验证请求url中的secret参数的值是否是约定的秘钥。
  它的nginx配置文件是这样的:

worker_processes  1;
error_log logs/error.log debug;
master_process off;
daemon off;
events {
worker_connections  1024;
}

http {
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
listen       8001;
server_name  localhost;
access_log  /tmp/access.log;
error_log  /tmp/error.log debug;
location / {
root   html;
index  index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
location = /mysecert {
# 只有传递的secret参数值为secretpassword的时候才通过验证
# 1 通过验证页面显示“secret right”
# 2 不通过验证页面显示“secret wrong”
# 比如
# http://abc.com:8001?secret=secretpassword通过
# http://abc.com:8001?secret=123不通过
mysecret secretpassword;
}
}
}
  
  location为/mysecret的时候,需要传递值为secretpassword的mysecret参数。页面会返回200并显示secret right,否则页面返回200并显示secret wrong。
  配置文件这里有几个地方注意下:
  为了调试方便,调整了几个地方:

worker_processes  1;
master_process off;
daemon off;

access_log  /tmp/access.log;
error_log  /tmp/error.log debug;
  而且在configure的时候我也加上了--with-debug参数

./configure --add-module=/home/yejianfeng/nginx/nginx_module/mysecret2/ --prefix=/home/yejianfeng/nginx/nginx/ --with-debug
  这样让调试更加方便

具体代码
  完整的代码可以看:https://github.com/jianfengye/MyWorks/tree/master/nginx_module_mysecret
  有几个地方要说明:
  1 这个模块由于有从配置文件中读取的信息,所以它是有属于自己模块的配置文件结构的

typedef struct {
ngx_str_t secret;
} ngx_http_mysecret_conf_t;
  所以有自己的配置文件,那么在模块构造模块上下文的时候create_loc_conf的阶段就多一个功能是初始化配置文件结构
  // 定义上下文, 只会在location中出现,所以都为null
  static ngx_http_module_t ngx_http_mysecret_module_ctx = {
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  ngx_http_mysecret_create_loc_conf,  //这里有使用自己的配置结构
  NULL
  };
  其中ngx_http_mysecret_create_loc_conf只要做的事情是初始化配置文件
  2 如何将配置文件nginx.conf中的mysecret的一个参数放在配置文件结构中呢?
  在ngx_http_mysecret这个命令回调函数中,有个ngx_conf_set_str_slot,这个是nginx预设的14个读取配置文件的函数之一,调用它就可以把nginx.conf中的secrect秘钥读取到配置文件结构中了。
  3 在handler中怎么获取配置文件结构呢?
  现在读取配置文件结束了,也构造了配置文件结构,到具体的处理http请求的阶段,如何获取这个结构呢?

ngx_http_mysecret_conf_t *mycf;
mycf = ngx_http_get_module_loc_conf(r, ngx_http_mysecret_module);
  使用这个方法就能在handler中获取到自定义的配置文件结构了。
  获取配置结构后,后面的问题就是如何获取请求参数呢
  ngx_http_request_t中的args参数就是获取请求参数的
  比如http://abc.com?a=s&b=2 那么args就是ngx_string("a=s&b=2")
  后面就可以使用nginx自定义的ngx_strncasecmp进行字符比较等操作了。
  好了,完整的一个验证请求参数的模块就写完了。

模块变种
  有人会对nginx.conf文件有点不舒服,可能希望设置验证秘钥是分为两个步骤:
  设置秘钥和验证秘钥
  即配置文件大致变成现在的样子:

location = /mysecert {
# 只有传递的secret参数值为secretpassword的时候才通过验证
# 1 通过验证页面显示“secret right”
# 2 不通过验证页面显示“secret wrong”
# 比如
# http://abc.com:8001?secret=secretpassword通过
# http://abc.com:8001?secret=123不通过
setmysecret secretpassword;
checksecret;
}
  原来的mysecret被两个命令setmysecret和checksecret替换了
  这两个命令的功能其实是不一样的,setmysecret只是读取配置文件,并不会对请求做任何操作,而checksecret是直接修改请求的。
  其实上一个例子稍微改一改就可以达到这样的目的:
  https://github.com/jianfengye/MyWorks/tree/master/nginx_module_mysecret2
  定义模块命令的结构就变成:

static ngx_command_t ngx_http_mysecret_commands[] = {
{
ngx_string("setmysecret"),
NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_mysecret_conf_t, secret),
NULL,
},
{
ngx_string("checksecret"),
NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
ngx_http_mysecret,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL,
},
ngx_null_command
};
  这里的setmysecret直接使用nginx预设的ngx_conf_set_str_slot方法,它就不需要有任何定义handler的操作了。事实上,nginx很多模块的像setmysecret这样的读取配置文件的命令(不做任何http请求的操作)都是直接使用nginx预设的14种方法的。具体的使用在《深入理解Nginx》第四章中有详细说明了。
  自然在checksecret命令中就不需要再读取参数了(也没有参数了,所以要注意这个命令中的命令类型要设置上NGX_CONF_NOARGS)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-90790-1-1.html 上篇帖子: nginx 截断日志一个批处理 下篇帖子: Windows下nginx定时分割日志
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表