• 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$ { #
                root   abcd;
            } 
            location @redo { #定义一个 Location块,且该块不能被外部Client 所访问,只能被Nginx内部配置指令所访问
                root   redo;
            } 
            location /tryfile {
                try_files $uri @redo ;#nginx内部命令才能使用@location配置
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    更多匹配规则见官网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():
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

  • 相关阅读:
    Pasta:HHE Optimized Stream Cipher
    做这么多年程序员了,才把ELK和springboot的日志解决方案弄明白
    合并k个已排序的链表
    华为云 MRS 基于 Apache Hudi 极致查询优化的探索实践
    2022年湖北中级工程师职称可以评哪些专业?甘建二
    PDF文件太大怎么办?三招教会你PDF文件压缩
    MySQL—Apache+PHP+MySQL实现网上社区
    LeetCode题目笔记——561. 数组拆分
    怎么监控上网记录?监控上网记录的软件推荐
    netty系列之:kequeue传输协议详解
  • 原文地址:https://blog.csdn.net/qq_22351805/article/details/126079757