mirror of
https://github.com/status-im/eth-rpc-proxy.git
synced 2026-08-31 03:31:14 +00:00
118 lines
3.6 KiB
Lua
118 lines
3.6 KiB
Lua
local http = require("resty.http")
|
|
local json = require("cjson")
|
|
local resolver_utils = require("utils.resolver_utils")
|
|
|
|
local M = {}
|
|
local function read_config_from_url(url)
|
|
if not url or url == "" then
|
|
return nil, "URL is invalid or not provided"
|
|
end
|
|
|
|
local httpc = http.new()
|
|
local custom_dns = os.getenv("CUSTOM_DNS")
|
|
local request_url = url
|
|
|
|
-- Resolve URL using custom DNS if available
|
|
if custom_dns and custom_dns ~= "" then
|
|
local resolved_url, resolve_err = resolver_utils.resolve_url_with_custom_dns(url, custom_dns)
|
|
if not resolved_url then
|
|
ngx.log(ngx.ERR, "Failed to resolve URL with custom DNS: ", resolve_err)
|
|
request_url = url -- Fall back to original URL
|
|
else
|
|
request_url = resolved_url
|
|
end
|
|
end
|
|
|
|
local res, err = httpc:request_uri(request_url, {
|
|
method = "GET",
|
|
headers = {
|
|
["Content-Type"] = "application/json",
|
|
},
|
|
ssl_verify = false,
|
|
})
|
|
|
|
if not res then
|
|
ngx.log(ngx.ERR, "Failed to fetch configuration from URL: ", err)
|
|
return nil, err
|
|
end
|
|
|
|
if res.status ~= 200 then
|
|
ngx.log(ngx.ERR, "Non-200 response from URL: ", res.status)
|
|
return nil, "HTTP error: " .. res.status
|
|
end
|
|
|
|
ngx.log(ngx.INFO, "Successfully fetched configuration from URL")
|
|
return res.body, nil
|
|
end
|
|
|
|
-- Function to read configuration from file
|
|
local function read_config_from_file(filepath)
|
|
ngx.log(ngx.INFO, "Reading configuration from file: ", filepath)
|
|
if not filepath or filepath == "" then
|
|
return nil, "Filepath is invalid or not provided"
|
|
end
|
|
|
|
local file = io.open(filepath, "r")
|
|
if not file then
|
|
ngx.log(ngx.ERR, "Failed to open file: ", filepath)
|
|
return nil, "File open error"
|
|
end
|
|
|
|
local content = file:read("*all")
|
|
file:close()
|
|
ngx.log(ngx.INFO, "Successfully read configuration from file")
|
|
return content, nil
|
|
end
|
|
|
|
-- Main provider reload function
|
|
function M.reload_providers(premature, url, fallbackLocalConfig)
|
|
if premature then
|
|
return
|
|
end
|
|
|
|
ngx.log(ngx.INFO, "Reloading providers")
|
|
|
|
-- Attempt to load configuration from URL
|
|
local config, err = read_config_from_url(url)
|
|
if not config then
|
|
ngx.log(ngx.ERR, "Failed to load configuration from URL: ", err)
|
|
|
|
-- Attempt to load configuration from file
|
|
local file_config, file_err = read_config_from_file(fallbackLocalConfig)
|
|
if not file_config then
|
|
ngx.log(ngx.ERR, "Failed to load configuration from fallback file: ", file_err)
|
|
return
|
|
end
|
|
config = file_config
|
|
end
|
|
|
|
-- Parse and transform provider configuration
|
|
local parsed_config, parse_err = json.decode(config)
|
|
if not parsed_config then
|
|
ngx.log(ngx.ERR, "Failed to parse provider config: ", parse_err)
|
|
return
|
|
end
|
|
|
|
-- Clear existing providers
|
|
ngx.shared.providers:flush_all()
|
|
|
|
-- Store providers by chain/network
|
|
for _, chain in ipairs(parsed_config.chains or {}) do
|
|
local key = chain.name .. ":" .. chain.network
|
|
ngx.shared.providers:set(key, json.encode(chain.providers))
|
|
ngx.log(ngx.INFO, "Loaded providers for ", key, " (", #chain.providers, " providers)")
|
|
end
|
|
|
|
ngx.log(ngx.INFO, "Providers reloaded and stored by chain/network")
|
|
end
|
|
|
|
-- Scheduler to call reload_providers
|
|
function M.schedule_reload_providers(url, fallbackLocalConfig)
|
|
local ok, err = ngx.timer.at(0, M.reload_providers, url, fallbackLocalConfig)
|
|
if not ok then
|
|
ngx.log(ngx.ERR, "Failed to create timer: ", err)
|
|
end
|
|
end
|
|
|
|
return M
|