feat(apisix): add Cloudron package
- Implements Apache APISIX packaging for Cloudron platform. - Includes Dockerfile, CloudronManifest.json, and start.sh. - Configured to use Cloudron's etcd addon. 🤖 Generated with Gemini CLI Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
203
CloudronPackages/APISIX/apisix-source/apisix/wasm.lua
Normal file
203
CloudronPackages/APISIX/apisix-source/apisix/wasm.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--
|
||||
-- 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 core = require("apisix.core")
|
||||
local type = type
|
||||
local support_wasm, wasm = pcall(require, "resty.proxy-wasm")
|
||||
local ngx_var = ngx.var
|
||||
|
||||
|
||||
local schema = {
|
||||
type = "object",
|
||||
properties = {
|
||||
conf = {
|
||||
oneOf = {
|
||||
{ type = "object", minProperties = 1},
|
||||
{ type = "string", minLength = 1},
|
||||
}
|
||||
},
|
||||
},
|
||||
required = {"conf"}
|
||||
}
|
||||
local _M = {}
|
||||
|
||||
|
||||
local function check_schema(conf)
|
||||
return core.schema.check(schema, conf)
|
||||
end
|
||||
|
||||
|
||||
local function get_plugin_ctx_key(ctx)
|
||||
return ctx.conf_type .. "#" .. ctx.conf_id
|
||||
end
|
||||
|
||||
local function fetch_plugin_ctx(conf, ctx, plugin)
|
||||
if not conf.plugin_ctxs then
|
||||
conf.plugin_ctxs = {}
|
||||
end
|
||||
|
||||
local ctxs = conf.plugin_ctxs
|
||||
local key = get_plugin_ctx_key(ctx)
|
||||
local plugin_ctx = ctxs[key]
|
||||
local err
|
||||
if not plugin_ctx then
|
||||
if type(conf.conf) == "table" then
|
||||
plugin_ctx, err = wasm.on_configure(plugin, core.json.encode(conf.conf))
|
||||
elseif type(conf.conf) == "string" then
|
||||
plugin_ctx, err = wasm.on_configure(plugin, conf.conf)
|
||||
else
|
||||
return nil, "invalid conf type"
|
||||
end
|
||||
if not plugin_ctx then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
ctxs[key] = plugin_ctx
|
||||
end
|
||||
|
||||
return plugin_ctx
|
||||
end
|
||||
|
||||
|
||||
local function http_request_wrapper(self, conf, ctx)
|
||||
local name = self.name
|
||||
local plugin_ctx, err = fetch_plugin_ctx(conf, ctx, self.plugin)
|
||||
if not plugin_ctx then
|
||||
core.log.error(name, ": failed to fetch wasm plugin ctx: ", err)
|
||||
return 503
|
||||
end
|
||||
|
||||
local ok, err = wasm.on_http_request_headers(plugin_ctx)
|
||||
if not ok then
|
||||
core.log.error(name, ": failed to run wasm plugin: ", err)
|
||||
return 503
|
||||
end
|
||||
|
||||
-- $wasm_process_req_body is predefined in ngx_tpl.lua
|
||||
local handle_body = ngx_var.wasm_process_req_body
|
||||
if handle_body ~= '' then
|
||||
-- reset the flag so we can use it for the next Wasm plugin
|
||||
-- use ngx.var to bypass the cache
|
||||
ngx_var.wasm_process_req_body = ''
|
||||
|
||||
local body, err = core.request.get_body()
|
||||
if err ~= nil then
|
||||
core.log.error(name, ": failed to get request body: ", err)
|
||||
return 503
|
||||
end
|
||||
|
||||
local ok, err = wasm.on_http_request_body(plugin_ctx, body, true)
|
||||
if not ok then
|
||||
core.log.error(name, ": failed to run wasm plugin: ", err)
|
||||
return 503
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function header_filter_wrapper(self, conf, ctx)
|
||||
local name = self.name
|
||||
local plugin_ctx, err = fetch_plugin_ctx(conf, ctx, self.plugin)
|
||||
if not plugin_ctx then
|
||||
core.log.error(name, ": failed to fetch wasm plugin ctx: ", err)
|
||||
return 503
|
||||
end
|
||||
|
||||
local ok, err = wasm.on_http_response_headers(plugin_ctx)
|
||||
if not ok then
|
||||
core.log.error(name, ": failed to run wasm plugin: ", err)
|
||||
return 503
|
||||
end
|
||||
|
||||
-- $wasm_process_resp_body is predefined in ngx_tpl.lua
|
||||
local handle_body = ngx_var.wasm_process_resp_body
|
||||
if handle_body ~= '' then
|
||||
-- reset the flag so we can use it for the next Wasm plugin
|
||||
-- use ngx.var to bypass the cache
|
||||
ngx_var.wasm_process_resp_body = ""
|
||||
ctx["wasm_" .. name .. "_process_resp_body"] = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function body_filter_wrapper(self, conf, ctx)
|
||||
local name = self.name
|
||||
|
||||
local enabled = ctx["wasm_" .. name .. "_process_resp_body"]
|
||||
if not enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local plugin_ctx, err = fetch_plugin_ctx(conf, ctx, self.plugin)
|
||||
if not plugin_ctx then
|
||||
core.log.error(name, ": failed to fetch wasm plugin ctx: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = wasm.on_http_response_body(plugin_ctx)
|
||||
if not ok then
|
||||
core.log.error(name, ": failed to run wasm plugin: ", err)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function _M.require(attrs)
|
||||
if not support_wasm then
|
||||
return nil, "need to build APISIX-Runtime to support wasm"
|
||||
end
|
||||
|
||||
local name = attrs.name
|
||||
local priority = attrs.priority
|
||||
local plugin, err = wasm.load(name, attrs.file)
|
||||
if not plugin then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
local mod = {
|
||||
version = 0.1,
|
||||
name = name,
|
||||
priority = priority,
|
||||
schema = schema,
|
||||
check_schema = check_schema,
|
||||
plugin = plugin,
|
||||
type = "wasm",
|
||||
}
|
||||
|
||||
if attrs.http_request_phase == "rewrite" then
|
||||
mod.rewrite = function (conf, ctx)
|
||||
return http_request_wrapper(mod, conf, ctx)
|
||||
end
|
||||
else
|
||||
mod.access = function (conf, ctx)
|
||||
return http_request_wrapper(mod, conf, ctx)
|
||||
end
|
||||
end
|
||||
|
||||
mod.header_filter = function (conf, ctx)
|
||||
return header_filter_wrapper(mod, conf, ctx)
|
||||
end
|
||||
|
||||
mod.body_filter = function (conf, ctx)
|
||||
return body_filter_wrapper(mod, conf, ctx)
|
||||
end
|
||||
|
||||
-- the returned values need to be the same as the Lua's 'require'
|
||||
return true, mod
|
||||
end
|
||||
|
||||
|
||||
return _M
|
Reference in New Issue
Block a user