apisix源码分析-处理用户请求(5)

apisix源码分析-处理用户请求(5)

apisix 如何处理用户的请求?

api_ctx

在执行开始前, apisix 会给 ngx.ctx 增加一个变量 ngx.ctx.api_ctx 的变量。

1
2
api_ctx = core.tablepool.fetch("api_ctx", 0, 32) 
ngx_ctx.api_ctx = api_ctx

变量从 “api_ctx” 的 table 池( lua-tablepool) 中取出,用完后还给池。

(lua-tablepool 中一个 table 变量重复使用 20000 次后就会被新的取代)

上面的两行代码在 ssl 阶段和 access 阶段都存在,但是存储的内容是不同的。

ssl 阶段是证书信息,access 阶段是 route 相关的信息

ssl

ssl 阶段负责设置证书。 证书的设置可以看看 ngx.ssl 的相关说明,在 ssl_certificate_by_lua_block 阶段通过 ngx.ssl 设置证书和私钥来配置域名证书。

init_work : 初始化 ssl_certificates 变量,用来和 etcd 同步数据

1
2
3
4
5
6
7
ssl_certificates, err = core.config.new("/ssl", {
automatic = true,
item_schema = core.schema.ssl,
checker = function (item, schema_type)
return apisix_ssl.check_ssl_conf(true, item)
end,
})

证书匹配

调用了 ssl/router/radixtree_sni.lua 的 match_and_set 。

  • 建立域名查询树

    radixtree_router 初始化 radixtree 来存储域名信息

    radixtree_router_ver 存储 配置版本,通过版本号来决定是否需要重建 radixtree

  • 域名会通过 字符串反向(sni:reverse()) 后在 radixtree 中查询。

    api_ctx.matched_sni 存储匹配的域名

    api_ctx.matched_ssl 存储对应的证书信息

域名查询树建立

create_router(ssl_certificates.values)

对象

1
2
3
4
5
6
7
8
9
10
route_items[idx] = {
paths = sni, -- 反向后的域名
handler = function (api_ctx) -- 回调函数
if not api_ctx then
return
end
api_ctx.matched_ssl = ssl
api_ctx.matched_sni = sni
end
}

证书有两种,全匹配证书,泛域名证书。

1
2
3
4
5
6
for _, msni in ipairs(api_ctx.matched_sni) do
-- 完全匹配 或者 相对于msni sni_srv 后面没有点(泛匹配)?
if sni_rev == msni or not str_find(sni_rev, ".", #msni) then
matched = true
end
end

按照 redixtree 最长匹配原则,证书会优先匹配到全匹配证书。

access

apisix 匹配路由是在 access 阶段完成的,功能由 router_http.match(api_ctx) 提供

apisix源码分析-处理用户请求(5)

https://beixiu.net/apisix-source-5/

作者

张巍

发布于

2023-08-20

更新于

2023-08-20

许可协议

评论