Nginx基础入门006(nginx 实战教程)
nanshan 2024-10-22 12:57 12 浏览 0 评论
这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。
- 上一篇: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 ~
相关推荐
- F5负载均衡器如何通过irules实现应用的灵活转发?
-
F5是非常强大的商业负载均衡器。除了处理性能强劲,以及高稳定性之外,F5还可以通过irules编写强大灵活的转发规则,实现web业务的灵活应用。irules是基于TCL语法的,每个iRules必须包含...
- 映射域名到NAS
-
前面介绍已经将域名映射到家庭路由器上,现在只需要在路由器上设置一下端口转发即可。假设NAS在内网的IP是192.168.1.100,NAS管理端口2000.你的域名是www.xxx.com,配置外部端...
- 转发(Forward)和重定向(Redirect)的区别
-
转发是服务器行为,重定向是客户端行为。转发(Forward)通过RequestDispatcher对象的forward(HttpServletRequestrequest,HttpServletRe...
- SpringBoot应用中使用拦截器实现路由转发
-
1、背景项目中有一个SpringBoot开发的微服务,经过业务多年的演进,代码已经累积到令人恐怖的规模,亟需重构,将之拆解成多个微服务。该微服务的接口庞大,调用关系非常复杂,且实施重构的人员大部分不是...
- 公司想搭建个网站,网站如何进行域名解析?
-
域名解析是将域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转...
- 域名和IP地址什么关系?如何通过域名解析IP?
-
一般情况下,访客通过域名和IP地址都能访问到网站,那么两者之间有什么关系吗?本文中科三方针对域名和IP地址的关系和区别,以及如何实现域名与IP的绑定做下介绍。域名与IP地址之间的关系IP地址是计算机的...
- 分享网站域名301重定向的知识
-
网站域名做301重定向操作时,一般需要由专业的技术来协助完成,如果用户自己在维护,可以按照相应的说明进行操作。好了,下面说说重点,域名301重定向的操作步骤。首先,根据HTTP协议,在客户端向服务器发...
- NAS外网到底安全吗?一文看懂HTTP/HTTPS和SSL证书
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:可爱的小cherry搭好了NAS,但是不懂做好网络加密,那么隐私泄露也会随时发生!大家好,这里是Cherry,喜爱折腾、玩数码,热衷于分享数...
- ForwardEmail免费、开源、加密的邮件转发服务
-
ForwardEmail是一款免费、加密和开源的邮件转发服务,设置简单只需4步即可正常使用,通过测试来看也要比ImprovMX好得多,转发近乎秒到且未进入垃圾箱(仅以Mailbox.org发送、Out...
- 使用CloudFlare进行域名重定向
-
当网站变更域名的时候,经常会使用域名重定向的方式,将老域名指向到新域名,这通常叫做:URL转发(URLFORWARDING),善于使用URL转发,对SEO来说非常有用,因为用这种方式能明确告知搜索引...
- 要将端口5002和5003通过Nginx代理到一个域名上的操作笔记
-
要将端口5002和5003通过Nginx代理到域名www.4rvi.cn的不同路径下,请按照以下步骤配置Nginx:步骤说明创建或编辑Nginx配置文件通常配置文件位于/etc/nginx/sites...
- SEO浅谈:网站域名重定向的三种方式
-
在大多数情况下,我们输入网站访问网站的时候,很难发现www.***.com和***.com的区别,因为一般的网站主,都会把这两个域名指向到同一网站。但是对于网站运营和优化来说,www.***.com和...
- 花生壳出现诊断域名与转发服务器ip不一致的解决办法
-
出现诊断域名与转发服务器ip不一致您可以:1、更改客户端所处主机的drs为223.5.5.5备用dns为119.29.29.29;2、在windows上进入命令提示符输入ipconfig/flush...
- 涨知识了!带你认识什么是域名
-
1、什么是域名从技术角度来看,域名是在Internet上解决IP地址对应的一种方法。一个完整的域名由两个或两个以上部分组成,各部分之间用英文的句号“.”来分隔。如“abc.com”。其中“com”称...
- 域名被跳转到其他网站是怎么回事
-
当你输入域名时被跳转到另一个网站,这可能是由几种原因造成的:一、域名可能配置了域名转发服务。无论何时有人访问域名,比如.com、.top等,都会自动重定向到另一个指定的URL,这通常是在域名注册商设...
你 发表评论:
欢迎- 一周热门
-
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
[常用工具] OpenCV_contrib库在windows下编译使用指南
-
WindowsServer2022|配置NTP服务器的命令
-
Ubuntu系统Daphne + Nginx + supervisor部署Django项目
-
WIN11 安装配置 linux 子系统 Ubuntu 图形界面 桌面系统
-
解决Linux终端中“-bash: nano: command not found”问题
-
NBA 2K25虚拟内存不足/爆内存/内存占用100% 一文速解
-
Linux 中的文件描述符是什么?(linux 打开文件表 文件描述符)
-
K3s禁用Service Load Balancer,解决获取浏览器IP不正确问题
-
- 最近发表
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)