如何在路由请求之前在 haproxy 中发送来自 lua 的 https 请求?
how to send https request from lua in haproxy before routing request?
我使用了 haproxy Socket class 作为概述 https://www.haproxy.com/blog/5-ways-to-extend-haproxy-with-lua/#actions 从 lua 代码向外部服务发出 http 请求(见下面的代码).
- 如何向服务发出 https 请求?
- 是否可以指定要连接的服务的域名而不是 IP 地址?
感谢任何帮助。
local function http_request(txn, data)
local addr = <external-IP>
local port = 80
-- Set up a request to the service
local hdrs = {
[1] = string.format('host: %s:%s', addr, port),
[2] = 'accept: */*',
[3] = 'connection: close'
}
local req = {
[1] = string.format('GET %s HTTP/1.1', data.path),
[2] = table.concat(hdrs, '\r\n'),
[3] = '\r\n'
}
req = table.concat(req, '\r\n')
-- Use core.tcp to get an instance of the Socket class
local socket = core.tcp()
socket:settimeout(data.timeout)
-- Connect to the service and send the request
if socket:connect(addr, port) then
if socket:send(req) then
-- Skip response headers
while true do
local line, _ = socket:receive('*l')
if not line then break end
if line == '' then break end
end
-- Get response body, if any
local content = socket:receive('*a')
return content
else
core.Alert('Could not connect to server (send)')
end
socket:close()
else
core.Alert('Could not connect to server (connect)')
end
end
最近在处理一个问题时,我发现我们无法传递域名。我正在使用 http.lua 库。此 http.lua 库使用套接字 class,就像您在代码中所做的那样。
同样,经过大量搜索后,我无法找到 dns 解析器库。一个是与 nginx lua 相关的东西,但它需要安装很多不同的 lua 库,所以我跳过了它。
我所做的工作是,在 HAProxy 中创建我自己的 dns 解析器服务 http://127.0.0.1:53535,如下所示
listen lua_dns
bind 127.0.0.1:53535
http-request do-resolve(txn.dstip,mydns,ipv4) hdr(ResolveHost),lower
http-request return status 200 content-type text/plain lf-string OK hdr ResolvedIp "%[var(txn.dstip)]"
对于此服务,我在请求中传递域名 header ResolveHost
并在响应中获取 IP header ResolvedIp
.
现在 lua 从 URL 解析域并调用 dns 解析器服务的函数如下
local function parse_domain(url)
local schema, host, _ = url:match("^(.*)://(.-)[?/](.*)$")
if not schema then
-- maybe path (request uri) is missing
schema, host = url:match("^(.*)://(.-)$")
if not schema then
core.Info("ERROR :: Could not parse URL: "..url)
return nil
end
end
return host
end
local function resolve_domain(domain)
local d = parse_domain(domain)
local r, msg = http.get{ url = "http://127.0.0.1:53535", headers={ResolveHost=d} }
if r == nil then
core.Info("ERROR: "..msg..". While resolving doamin: "..d)
return msg
end
return r.headers['resolvedip']
end
现在用gsub()URL中的域名替换解析的IP
url = string:gsub(domain_name, resolved_ip)
然后使用 http.lua
调用您的 API
local res, msg = http.get{ url=url, headers=headers }
此处 http.lua 库将处理 HTTP 和 HTTPS url。
我使用了 haproxy Socket class 作为概述 https://www.haproxy.com/blog/5-ways-to-extend-haproxy-with-lua/#actions 从 lua 代码向外部服务发出 http 请求(见下面的代码).
- 如何向服务发出 https 请求?
- 是否可以指定要连接的服务的域名而不是 IP 地址?
感谢任何帮助。
local function http_request(txn, data)
local addr = <external-IP>
local port = 80
-- Set up a request to the service
local hdrs = {
[1] = string.format('host: %s:%s', addr, port),
[2] = 'accept: */*',
[3] = 'connection: close'
}
local req = {
[1] = string.format('GET %s HTTP/1.1', data.path),
[2] = table.concat(hdrs, '\r\n'),
[3] = '\r\n'
}
req = table.concat(req, '\r\n')
-- Use core.tcp to get an instance of the Socket class
local socket = core.tcp()
socket:settimeout(data.timeout)
-- Connect to the service and send the request
if socket:connect(addr, port) then
if socket:send(req) then
-- Skip response headers
while true do
local line, _ = socket:receive('*l')
if not line then break end
if line == '' then break end
end
-- Get response body, if any
local content = socket:receive('*a')
return content
else
core.Alert('Could not connect to server (send)')
end
socket:close()
else
core.Alert('Could not connect to server (connect)')
end
end
最近在处理一个问题时,我发现我们无法传递域名。我正在使用 http.lua 库。此 http.lua 库使用套接字 class,就像您在代码中所做的那样。
同样,经过大量搜索后,我无法找到 dns 解析器库。一个是与 nginx lua 相关的东西,但它需要安装很多不同的 lua 库,所以我跳过了它。
我所做的工作是,在 HAProxy 中创建我自己的 dns 解析器服务 http://127.0.0.1:53535,如下所示
listen lua_dns
bind 127.0.0.1:53535
http-request do-resolve(txn.dstip,mydns,ipv4) hdr(ResolveHost),lower
http-request return status 200 content-type text/plain lf-string OK hdr ResolvedIp "%[var(txn.dstip)]"
对于此服务,我在请求中传递域名 header ResolveHost
并在响应中获取 IP header ResolvedIp
.
现在 lua 从 URL 解析域并调用 dns 解析器服务的函数如下
local function parse_domain(url)
local schema, host, _ = url:match("^(.*)://(.-)[?/](.*)$")
if not schema then
-- maybe path (request uri) is missing
schema, host = url:match("^(.*)://(.-)$")
if not schema then
core.Info("ERROR :: Could not parse URL: "..url)
return nil
end
end
return host
end
local function resolve_domain(domain)
local d = parse_domain(domain)
local r, msg = http.get{ url = "http://127.0.0.1:53535", headers={ResolveHost=d} }
if r == nil then
core.Info("ERROR: "..msg..". While resolving doamin: "..d)
return msg
end
return r.headers['resolvedip']
end
现在用gsub()URL中的域名替换解析的IP
url = string:gsub(domain_name, resolved_ip)
然后使用 http.lua
调用您的 APIlocal res, msg = http.get{ url=url, headers=headers }
此处 http.lua 库将处理 HTTP 和 HTTPS url。