【nginx】nginx处理HTTP请求的11个阶段

it2023-07-30  77

参考:http://www.imooc.com/wiki/nginxlesson/httpmodule01.html

11个阶段

typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, NGX_HTTP_POST_ACCESS_PHASE, NGX_HTTP_TRY_FILES_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE } ngx_http_phases;

POST_READ 阶段 (预备阶段) POST_READ 阶段是 Nginx 接收到 Http 请求完整头部后的处理阶段,这里主要使用的是 realip 模块获取用户的真实地址,方便后续对该 IP 进行限速或者过滤其请求等。SERVER_REWRITE 和 REWRITE 阶段(重定向) SERVER_REWRITE 和后面的 REWRITE 阶段一般是使用 rewrite 模块修改 Http请求的 uri,实现请求的控制。FIND_CONFIG 阶段 FIND_CONFIG 阶段只是做 location 的匹配项。PREACCESS、ACCESS 和 POST_ACCESS 阶段(权限相关) PREACCESS 阶段是在连接之前要做的访问控制, 这个阶段有 limit_conn 和 limit_req 等模块工作。ACCESS 阶段是解决用户能不能访问,比如根据用户名、密码限制用户访问(auth_basic 模块)、根据 ip 限制用户访问(access 模块)以及第三方模块认证限制用户的访问(auth_request模块)。POST_ACCESS 是在 ACCESS 之后要做的一些工作。 TRY_FILES 阶段 TRY_FILES 阶段为访问静态文件资源而设置的。有时候又称之为 PRECONTENT 阶段,即在 CONTENT 阶段之前做的事情。主要是 try_files 模块在此阶段工作。CONTENT 最重要的 CONTENT 是处理 Http 请求内容的阶段,大部分 HTTP 模块介入这个阶段,比如 index、autoindex、concat 以及反向代理的模块都是在这里生效的。LOG 阶段 LOG 是处理完请求后的日志记录阶段,如 access_log 模块。

Tips:

所有的 Http请求必须都是从上到下,一个接一个阶段执行的。

涉及到的模块

realip 模块

realip 模块是在 postread 阶段生效的,它的作用是:当本机的 nginx 处于一个反向代理的后端时获取到真实的用户 ip。 如果没有 realip 模块,Nginx 中的 $remote_addr 可能就不是客户端的真实 ip 了,而是代理主机的 ip。

#指定我们信任的后端代理服务器 set_real_ip_from 10.10.10.10; #为 off 时,nginx 会把 real_ip_header 指定的 Http头中的最后一个 ip 当成真实 ip; #为 on 时,nginx 会把最后一个不是信任服务器的 ip (前面设置的set_real_ip_from)当成真实 ip。 real_ip_recursive on; #告诉 nginx 真正的用户 ip 是存在 X-Forwarded-For 请求头中的。 real_ip_header X-Forwarded-For;

rewrite 模块

rewrite 模块的主要功能是改写请求的 uri。 它是 Nginx 默认安装的模块。rewrite 模块会根据正则匹配重写 uri,然后发起内部跳转再匹配 location, 或者直接做30x重定向返回客户端。rewrite 模块的指令有 break, if, return, rewrite, set 等,这些都是我们常用到的。

return 指令

Syntax: return code [text]; # return code URL; # return URL; Default: — Context: server, location, if

return 指令返回后,Http 请求将在 return 的阶段终止,后续阶段将无法进行,所以许多模块得不到执行。

return 200 "hello, world"

rewrite 指令

Syntax: rewrite regex replacement [flag]; Default: – Context: server, location, if

1、将 regex 指定的 url 替换成 replacement 这个新的 url,可以使用正则表达式及变量提取。 2、当 replacement 以 http:// 或者 https:// 或者 $schema 开头,则直接返回 302 重定向 3、替换后的 url 根据 flag 指定的方式进行处理

last: 用 replacement 这个 url 进行新的 location 匹配break: break 指令停止当前脚本指令的执行redirect:返回 302 重定向permanent: 返回 301 重定向

if 指令

Syntax: if (condition) { ... } Default: — Context: server, location

if 指令的条件表达式:

检查变量是否为空或者为 0将变量与字符串做匹配,使用 = 或者 !=将变量与正则表达式做匹配: ~ 或者 !~ 大小写敏感~* 或者 !~* 大小写不敏感 检查文件是否存在 -f 或者 !-f检查目录是否存在 -d 或者 !-d检查文件、目录、软链接是否存在 -e !-e是否为可执行文件 -x 或者 !-x

实例

if ($request_medthod = POST){ return 405; } if($invalid_refer){ return 403; }

location 匹配

server { server_name location.test.com; listen 8010; location = / { return 200 "精确匹配/"; } location ~* /ma.*ch { return 200 "正则匹配/ma.*ch"; } location ~ /mat.*ch { return 200 "正则匹配/match.*"; } location = /test { return 200 "精确匹配/test"; } location ^~ /test/ { return 200 "前缀匹配/test"; } location ~ /test/he*o { return 200 "正则匹配/test/he*o"; } location / { return 200 "通配/"; } }
最新回复(0)