NGINX源码之:location

进入主题前,先来看下location的主要集中配置方式:

       location / {   //匹配所有的请求
            root   html;
            index  index.html index.htm;
        }
        location = /50x.html {  //精准匹配
            root   html;
        }
        
        location /static/ { #前缀匹配,当请求//static/a.txt,或者为/static均不能匹配,多了/或者少了/
            root   static; #相对NGINX的工作目录如:/usr/local/nginx/static/,假设请求是/static/a.txt,
                           #则查找的文件为/usr/local/nginx/static/static/a.txt
           #root   /opt/static; #以/开头的认为是绝对目录,查找目录为/opt/static/static
        }
        location ~ ^/abcd$ { #正则匹配,大小写敏感
            root   abcd;
        }   
        location ~* ^/abcd$ { #正则匹配,大小写不敏感
            root   abcd;
        } 
        location ^~ ^/abcd$ { #前缀字符串前加^~可以跳过正则表达式匹配,它不需要URI完全相等,只需要匹配上前缀而且此location是当下最长匹配即可,跟前缀匹配差不多,不过前缀匹配不能跳过正则匹配。
        } 
        location @redo { #定义一个 Location块,且该块不能被外部Client 所访问,只能被Nginx内部配置指令所访问
            root   redo;
        } 
        location /tryfile {
            try_files $uri @redo ;#nginx内部命令才能使用@location配置
        }
        location /hei/ { 
            alias /hello/info/; 
        }      # 真实路径 /hello/info/index.html 
        location /hei/ { 
            root /hello/info/; 
        }      # 真实路径 /hello/info/hei/index.html

更多匹配规则见官网location配置
一、ngx_http_core_location
location配置结构生成的部分,在博客NGINX源码之:模块配置解析(1)已做介绍,下面主要对该方法中的其他细节做解读。
除生成配置外,主要还包括URL匹配规则解析,location配置命名,location配置块内命令解析
在这里插入图片描述

此时不同类型的location块的配置除了完成命名,还设置对应的类型:如 = 对应的类型是exact_match~与 ~* 对应regrex^~ 对应noregex@ 对应named,另外还有noname类型,并不是在此处设置,而是在解析rewrite命令或者limit except命令时设置

location配置块内的命令解析这里就不解读了,用到的时候再看吧,只找查找对应命令的解析方法,前面篇章有介绍过如何查找。
主要可关注root、index、proxy_pass、rewrite、deny、satisfy 等
NGINX源码之:模块配置解析(1)可知,当某个server块完成所有的location块解析后,会生成一个locations队列,location块中嵌套的location也会生成一个location队列:
在这里插入图片描述

ngx_http_add_location() 构建locations队列时,excat_match/regex/named/noname类型的location配置均设置到(ngx_http_location_queue_t)lq的exact成员中,剩余没有类型符开头的location配置均设置到inclusive中
在这里插入图片描述

二、构建location树:ngx_http_init_locations与ngx_http_init_static_location_trees
在解析完http块内所有内容后,ngx_http_block()方法中,开始进入构建location树
1、ngx_http_init_locations()
该方法中首先对locations队列进行排序:
在这里插入图片描述

排序完后的队列: (exact_match 或 inclusive) (排序好的,如果某个exact_match名字和inclusive location相同,exact_match排在前面) | regex(regex节点间不排序)| named(name小的在前) | noname(noname节点间不排序)

排序完成之后,完成队列裁剪,将精准匹配与前缀匹配类型继续留在locations队列中,将regex类型节点和named类型节点添加到各自对应队列,noname的直接剪除:
在这里插入图片描述
来看个示例:
在这里插入图片描述

这里有个注意点:lq = (ngx_http_location_queue_t *) q;
因为ngx_http_location_queue_t 的结构体头一个成员就是queue,因此结构体的首地址也是queue的首地址

2、 ngx_http_init_static_location_trees()
在这里插入图片描述

下面对其中的几个重点方法展开下:
2.1、ngx_http_join_exact_locations()
在这里插入图片描述
2.2、ngx_http_create_locations_list()
在这里插入图片描述
list创建如图:在这里插入图片描述
2.3、ngx_http_create_locations_tree()
在这里插入图片描述

注意:node->tree的树构建时,入参prefix时当前node节点处理的prefix+当前name的长度如:当前的node是/,当前处理的prefix是0,那么当前node的tree,即当前node的list构建树时,ngx_http_create_locations_tree,传入的prefix就是1。主要为了构建node->tree的节点时,tree节点的name去掉前缀部分如:/a1,再/的node->list中,参与/的node->tree的构建,那么tree中/a1节点的name为:a1

创建的树结构如下:
在这里插入图片描述

三、location查找:ngx_http_core_find_location
在这里插入图片描述
主要来看下ngx_http_core_find_static_location():
在这里插入图片描述在这里插入图片描述在这里插入图片描述
可以看出,在static_locations满足前缀匹配查找后,r->loc_conf,是不断更改为下一个匹配的节点的loc_conf(精准或者还要继续递归tree子树),如果没有精准找到对应的节点,那么使用最后一个前缀匹配的节点的loc_conf。当匹配到前缀匹配的节点时,前缀匹配的节点分两种,一种是普通的前缀,一种是以^~开头的location前缀匹配,这种location的loc_conf会设置为noregex,这里的意思很明确,就是跳过正则匹配,从代码可以看过,匹配的前缀匹配节点,那么后面的正则匹配流程就不走了。
因此在ngx_http_core_find_location中,首先精准匹配,然后再前缀匹配,如果前缀匹配的节点不是^~ 类型但是又有正则匹配满足的话,则使用正则匹配的loc_conf。因此匹配顺序:精准 > ^~类型前缀匹配 > 正则 > 前缀匹配

关于auto_redirect的设置,主要可以参考ngx_http_proxy_pass()
在这里插入图片描述
这段赋值代码, 除了在proxy模块中, 同时还存在与fastcgi, grpc, memcached, scgi, uwsgi模块中。这里关系到一个重定向问题可参考auto_redirect问题这里不做讨论

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值