blob: 9f63acd27fcf666bc6270e3fb9d24a66621e14f5 [file] [log] [blame]
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local require = require
local router = require("apisix.utils.router")
local apisix_router = require("apisix.router")
local plugin_mod = require("apisix.plugin")
local ip_restriction = require("apisix.plugins.ip-restriction")
local core = require("apisix.core")
local ipairs = ipairs
local type = type
local _M = {}
local match_opts = {}
local has_route_not_under_apisix
local interceptors = {
["ip-restriction"] = {
run = function (conf, ctx)
return ip_restriction.access(conf, ctx)
end,
schema = ip_restriction.schema,
}
}
_M.interceptors_schema = {
["$comment"] = "this is the mark for our interceptors schema",
type = "array",
items = {
type = "object",
minItems = 1,
properties = {
name = {
type = "string",
enum = {},
},
conf = {
type = "object",
}
},
required = {"name", "conf"},
dependencies = {
name = {
oneOf = {}
}
}
}
}
for name, attrs in pairs(interceptors) do
core.table.insert(_M.interceptors_schema.items.properties.name.enum, name)
core.table.insert(_M.interceptors_schema.items.dependencies.name.oneOf, {
properties = {
name = {
enum = {name},
},
conf = attrs.schema,
}
})
end
local fetch_api_router
do
local routes = {}
function fetch_api_router()
core.table.clear(routes)
has_route_not_under_apisix = false
for _, plugin in ipairs(plugin_mod.plugins) do
local api_fun = plugin.api
if api_fun then
local name = plugin.name
local api_routes = api_fun()
core.log.debug("fetched api routes: ",
core.json.delay_encode(api_routes, true))
for _, route in ipairs(api_routes) do
local typ_uri = type(route.uri)
if not has_route_not_under_apisix then
if typ_uri == "string" then
if not core.string.has_prefix(route.uri, "/apisix/") then
has_route_not_under_apisix = true
end
else
for _, uri in ipairs(route.uri) do
if not core.string.has_prefix(uri, "/apisix/") then
has_route_not_under_apisix = true
break
end
end
end
end
core.table.insert(routes, {
methods = route.methods,
paths = route.uri,
handler = function (api_ctx, skip_global_rule)
local code, body
local metadata = plugin_mod.plugin_metadata(name)
if metadata and metadata.value.interceptors then
for _, rule in ipairs(metadata.value.interceptors) do
local f = interceptors[rule.name]
if f == nil then
core.log.error("unknown interceptor: ", rule.name)
else
code, body = f.run(rule.conf, api_ctx)
if code or body then
return core.response.exit(code, body)
end
end
end
end
if not skip_global_rule then
plugin_mod.run_global_rules(api_ctx,
apisix_router.global_rules, nil)
end
code, body = route.handler(api_ctx)
if code or body then
core.response.exit(code, body)
end
end
})
end
end
end
return router.new(routes)
end
end -- do
function _M.has_route_not_under_apisix()
if has_route_not_under_apisix == nil then
return true
end
return has_route_not_under_apisix
end
function _M.match(api_ctx, skip_global_rule)
local api_router = core.lrucache.global("api_router", plugin_mod.load_times, fetch_api_router)
if not api_router then
core.log.error("failed to fetch valid api router")
return false
end
core.table.clear(match_opts)
match_opts.method = api_ctx.var.request_method
local ok = api_router:dispatch(api_ctx.var.uri, match_opts, api_ctx, skip_global_rule)
return ok
end
return _M