网站首页 > 精选教程 正文
这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。
- 上一篇:ailx10:Nginx基础入门005 ;
ailx10
网络安全优秀回答者
网络安全硕士
如何定义自己的HTTP模块?
首先问自己:
- 我希望自己的模块在哪个时刻开始处理请求?
- 是希望自己的模块对到达Nginx的所有请求都起作用?
- 还是希望只对某一类请求(URL匹配了location后表达式的请求)起作用?
mytest模块:
- 定义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
};
- 定义ctx指针
static ngx_http_module_t ngx_http_mytest_module_ctx = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
- 定义command指针
当在某个配置块中出现mytest配置项时,Nginx将会调用ngx_http_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
};
- set函数的实现,解析配置文件
首先找到mytest配置项所属的配置块。
clcf看上去像是location块内的数据结构,其实,它可以是main、srv或者loc级别配置项。
也就是说,在每个http{}和server{}内也都有一个ngx_http_core_loc_conf_t结构体。
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;
}
- 配置的处理函数实现
HTTP框架在接收完HTTP请求的头部后,会调用handler指向的方法。
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);
//如果不想处理请求中的包体,那么可以调用ngx_http_discard_request_body方法将接收自客户端的HTTP包体丢弃掉。
if (rc != NGX_OK) {
return rc;
}
// Send response header
ngx_str_t type = ngx_string("text/plain");
ngx_str_t response = ngx_string("Hello World!");
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = response.len;
r->headers_out.content_type = type;
/*
请求处理完毕后,需要向用户发送HTTP响应,告知客户端Nginx的执行结果。HTTP响应主要包括响应行、响应头部、包体三部分。
发送HTTP响应时需要执行发送HTTP头部(发送HTTP头部时也会发送响应行)和发送HTTP包体两步操作。
*/
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
// Send response body
ngx_buf_t *b;
b = ngx_create_temp_buf(r->pool, response.len);
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_memcpy(b->pos, response.data, response.len);
b->last = b->pos + response.len;
b->last_buf = 1;
ngx_chain_t out;
out.buf = b;
out.next = NULL;
return ngx_http_output_filter(r, &out);
}
Nginx HTTP处理的11个阶段:
各个阶段的http框架check函数见ngx_http_init_phase_handlers ,所有阶段的checker在ngx_http_core_run_phases中调用。
- NGX_HTTP_POST_READ_PHASE
//在接收到完整的HTTP头部后处理的HTTP阶段 主要是获取客户端真实IP,因为客户端到nginx可能通过了vanish等缓存,
//ngx_http_realip_module(ngx_http_realip_init->ngx_http_realip_handler)
NGX_HTTP_POST_READ_PHASE = 0, //该阶段方法有:ngx_http_realip_handler POST有"在....后"的意思,POST_READ应该就是在解析完请求行和头部行后
- NGX_HTTP_SERVER_REWRITE_PHASE
/*在还没有查询到URI匹配的location前,这时rewrite重写URL也作为一个独立的HTTP阶段 Server内请求地址重写阶段 */
NGX_HTTP_SERVER_REWRITE_PHASE, //该阶段handler方法有:ngx_http_rewrite_module(ngx_http_rewrite_init->ngx_http_rewrite_handler)
- NGX_HTTP_FIND_CONFIG_PHASE
/*根据URI寻找匹配的location,这个阶段通常由ngx_http_core_module模块实现,不建议其他HTTP模块重新定义这一阶段的行为*/
NGX_HTTP_FIND_CONFIG_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段 该阶段完成的是Nginx的特定任务,即进行Location定位
- NGX_HTTP_REWRITE_PHASE
//在NGX_HTTP_FIND_CONFIG_PHASE阶段寻找到匹配的location之后再修改请求的URI Location内请求地址重写阶段
/*在NGX_HTTP_FIND_CONFIG_PHASE阶段之后重写URL的意义与NGX_HTTP_SERVER_REWRITE_PHASE阶段显然是不同的,因为这两者会导致查找到不同的location块(location是与URI进行匹配的)*/
NGX_HTTP_REWRITE_PHASE,//该阶段handler方法有:ngx_http_rewrite_handler
- NGX_HTTP_POST_REWRITE_PHASE
/*这一阶段是用于在rewrite重写URL后,防止错误的nginx.conf配置导致死循环(递归地修改URI),因此,这一阶段仅由ngx_http_core_module模块处理。
目前,控制死循环的方式很简单,首先检查rewrite的次数,如果一个请求超过10次重定向,扰认为进入了rewrite死循环,这时在NGX_HTTP_POSTREWRITE_PHASE
阶段就会向用户返回500,表示服务器内部错误*/
NGX_HTTP_POST_REWRITE_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
- NGX_HTTP_PREACCESS_PHASE
/* NGX_HTTP_PRE_ACCESS_PHASE、NGX_HTTP_ACCESS_PHASE、NGX_HTTP_POST_ACCESS_PHASE,很好理解,做访问权限检查的前期、中期、后期工作,
其中后期工作是固定的,判断前面访问权限检查的结果(状态码存故在字段r->access_code内),如果当前请求没有访问权限,那么直接返回状
态403错误,所以这个阶段也无法去挂载额外的回调函数。*/
//处理NGX_HTTP_ACCESS_PHASE阶段前,HTTP模块可以介入的处理阶段
NGX_HTTP_PREACCESS_PHASE,//该阶段handler方法有:ngx_http_degradation_handler ngx_http_limit_conn_handler ngx_http_limit_req_handler ngx_http_realip_handler
- NGX_HTTP_ACCESS_PHASE
/*这个阶段用于让HTTP模块判断是否允许这个请求访问Nginx服务器*/
NGX_HTTP_ACCESS_PHASE,//该阶段handler方法有:ngx_http_access_handler ngx_http_auth_basic_handler ngx_http_auth_request_handler
- NGX_HTTP_POST_ACCESS_PHASE
/*当NGX_HTTP_ACCESS_PHASE阶段中HTTP模块的handler处理方法返回不允许访问的错误码时(实际是NGX_HTTP_FORBIDDEN或者NGX_HTTP_UNAUTHORIZED),
这个阶段将负责构造拒绝服务的用户响应。所以,这个阶段实际上用于给NGX_HTTP_ACCESS_PHASE阶段收尾*/
NGX_HTTP_POST_ACCESS_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
- NGX_HTTP_TRY_FILES_PHASE
/*这个阶段完全是为了try_files配置项而设立的。当HTTP请求访问静态文件资源时,try_files配置项可以使这个请求顺序地访问多个静态文件资源,
如果某一次访问失败,则继续访问try_files中指定的下一个静态资源。另外,这个功能完全是在NGX_HTTP_TRY_FILES_PHASE阶段中实现的*/
NGX_HTTP_TRY_FILES_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
- NGX_HTTP_CONTENT_PHASE
/* 其余10个阶段中各HTTP模块的处理方法都是放在全局的ngx_http_core_main_conf_t结构体中的,
也就是说,它们对任何一个HTTP请求都是有效的,NGX_HTTP_CONTENT_PHASE 仅仅针对某种请求唯一生效。
ngx_http_handler_pt处理方法不再应用于所有的HTTP请求,仅仅当用户请求的URI匹配了location时(也就是mytest配置项所在的location)才会被调用。
这也就意味着它是一种完全不同于其他阶段的使用方式。 因此,当HTTP模块实现了某个ngx_http_handler_pt处理方法并希望介入NGX_HTTP_CONTENT_PHASE阶
段来处理用户请求时,如果希望这个ngx_http_handler_pt方法应用于所有的用户请求,则应该在ngx_http_module_t接口的postconfiguration方法中,
向ngx_http_core_main_conf_t结构体的phases[NGX_HTTP_CONTENT_PHASE]动态数组中添加ngx_http_handler_pt处理方法;反之,如果希望这个方式
仅应用于URI匹配丁某些location的用户请求,则应该在一个location下配置项的回调方法中,把ngx_http_handler_pt方法设置到ngx_http_core_loc_conf_t
结构体的handler中。
注意ngx_http_core_loc_conf_t结构体中仅有一个handler指针,它不是数组,这也就意味着如果采用上述的第二种方法添加ngx_http_handler_pt处理方法,
那么每个请求在NGX_HTTP_CONTENT PHASE阶段只能有一个ngx_http_handler_pt处理方法。而使用第一种方法时是没有这个限制的,NGX_HTTP_CONTENT_PHASE阶
段可以经由任意个HTTP模块处理。 */
//用于处理HTTP请求内容的阶段,这是大部分HTTP模块最喜欢介入的阶段 //CONTENT_PHASE阶段的处理回调函数ngx_http_handler_pt比较特殊,见ngx_http_core_content_phase
NGX_HTTP_CONTENT_PHASE, //该阶段handler方法有:ngx_http_autoindex_handler ngx_http_dav_handler ngx_http_gzip_static_handler ngx_http_index_handler ngx_http_random_index_handler ngx_http_static_handler
- NGX_HTTP_LOG_PHASE
/*处理完请求后记录日志的阶段。例如,ngx_http_log_module模块就在这个阶段中加入了一个handler处理方法,使得每个HTTP请求处理完毕后会记录access_log日志*/
NGX_HTTP_LOG_PHASE //该阶段handler方法有: ngx_http_log_handler
博主ailx10 正在疯狂学习 觉得好的话 点个关注? .... bling ~
猜你喜欢
- 2024-10-06 在Nginx中使用 LuaJIT 判断变量是否是整数
- 2024-10-06 高级开发必须掌握Nginx之四,if、set、return
你 发表评论:
欢迎- 最近发表
-
- 我的世界光影MOD下载(我的世界光影mod下载安装)
- 我的世界1.7/1.8VoxelMap小地图MOD下载
- 我的世界1.7.10多世界 整合包(我的世界1.7.10forge整合包)
- 我的世界1.8最好用的修改器下载(我的世界1.8最好用的修改器下载安装)
- 我的世界更多弯曲动作MOD下载(我的世界更多弯曲动作mod下载手机版)
- 我的世界龙珠MOD下载(我的世界龙珠模组整合包下载)
- 我的世界1.7.10以太2 下载(我的世界以太2mod1.12.2)
- 我的世界虚拟人生MOD下载分享(我的世界虚拟人生下载安装)
- 我的世界无正版账号的简单联机方法(非网易版,仅适用于局域网)
- “我的语言极限,即是我的世界的极限。” ——《On Java》书籍推荐
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)