定义自己的HTTP模块

网友投稿 257 2022-09-26

定义自己的HTTP模块

决定自己的HTTP模块如何起作用

一个HTTP请求会被许多个配置项控制,这是因为一个HTTP请求可以被许多个HTTP模块同时处理,所以肯定会有一个先后顺序的问题。我们面临的问题:

我们希望自己的模块在哪个时刻开始处理请求?我们是希望自己的模块对到达Nginx的所有请求都起作用,还是只对某一类请求(如URI匹配了location后表达式的请求)起作用?

定义第一个HTTP模块介入Nginx的方式

模块并不对所有的HTTP请求起作用。在nginx.conf文件中的ngx_command_t ngx_= {{ ngx_string("mytest"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS, ngx_ NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command};

ngx_char * ngx_*cf, ngx_command_t *cmd, void *conf) { ngx_*clcf; /* 首先找到mytest配置项所属的配置块,clcf看上去像是location块内的数据结构,其实不然, * 它可以是main、src或者loc级别的配置项,也就是说,在每个 * ngx_ */ clcf = ngx_ngx_ /* HTTP框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段是,如果请求的主机域名、URL * 与mytest配置项所在的配置块相匹配,就将调用我们实现的ngx_ * 理这个请求 * */ clcf->handler = ngx_ return NGX_CONF_OK;}

当Nginx接收完HTTP请求的头部信息时,就会调用HTTP框架处理请求,NGX_HTTP_CONTENT_PHASE阶段将有可能调用mytest模块处理请求。在ngx_enum { // 在接收到完整的HTTP头部后处理的HTTP阶段 NGX_HTTP_POST_READ_PHASE = 0, /* 在还没有查询到URI匹配的location前,这时rewrite重写URL也作为一个独立的HTTP阶段 */ NGX_HTTP_SERVER_REWRITE_PHASE, /* 根据URI寻找匹配的location,这个阶段通常由ngx_ 不建议其他HTTP模块重新定义这一阶段的行为。 */ NGX_HTTP_FIND_CONFIG_PHASE, /* NGX_HTTP_FIND_CONFIG_PHASE阶段后重写URL的意义与NGX_HTTP_SERVER_REWRITE_PHASE阶段不同 因为这两者会导致查找到不同的location块(location是与URI进行匹配的) */ NGX_HTTP_REWRITE_PHASE, /* 该阶段用于在rewrite重写URL后跳到NGX_HTTP_FIND_CONFIG_PHASE,找到与新的URI匹配的location。 这一阶段无法由第三方HTTP模块处理,仅由ngx_ */ NGX_HTTP_POST_REWRITE_PHASE, // 处理NGX_HTTP_ACCESS_PHASE阶段前,HTTP模块可以介入的处理阶段 NGX_HTTP_PREACCESS_PHASE, // 这个阶段用于HTTP模块判断是否允许这个请求访问Nginx服务器 NGX_HTTP_ACCESS_PHASE, /* 当NGX_HTTP_ACCESS_PHASE阶段中HTTP模块的handler处理方法返回不允许访问的错误码时 (实际是NGX_HTTP_FORBIDDEN或者NGX_HTTP_UNAUTHORIZED),这个阶段负责构造拒绝服务的用户响应。 这个阶段实际上用于给NGX_HTTP_ACCESS_PHASE阶段收尾。 */ NGX_HTTP_POST_ACCESS_PHASE, /* 这个阶段完全是为try_files配置项而设立的。 当HTTP请求访问静态文件资源时,try_files配置项可以使这个请求顺序地访问多个静态文件资源。 如果某一次访问失败,则继续访问try_files中指定的下一个静态资源。 这个功能完全是在NGX_HTTP_TRY_FILES_PHASE阶段中实现的。 */ NGX_HTTP_PRECONTENT_PHASE, // 用于处理HTTP请求内容的阶段,这是大部分HTTP模块最喜欢介入的阶段 NGX_HTTP_CONTENT_PHASE, /* 处理完请求后记录日志的阶段。 ngx_ 使得每个HTTP请求处理完毕后会记录access_log日志 */ NGX_HTTP_LOG_PHASE} ngx_ngx_ngx_= { 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 */};

定义mytest模块

ngx_module_t ngx_= { NGX_MODULE_V1, &ngx_ /* module context */ ngx_ /* 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全局数组中。Nginx在启动时,会调用所有模块的初始化回调方法,当然,这个例子中我们没有实现它们(也没有实现HTTP框架初始化时会调用的ngx_http_module_t中的8个方法)。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:自适应模糊PID在反应釜温度控制中的应用
下一篇:Java版本和C++版本的二叉树序列化与反序列化
相关文章

 发表评论

暂时没有评论,来抢沙发吧~