gen_interface needs hostname

This commit is contained in:
Cloud Wu
2025-12-28 08:25:49 +08:00
parent e4a1250ebb
commit 2a5d6c38ae

View File

@@ -11,7 +11,6 @@ local pairs = pairs
local httpc = {} local httpc = {}
local async_dns local async_dns
function httpc.dns(server,port) function httpc.dns(server,port)
@@ -19,13 +18,38 @@ function httpc.dns(server,port)
dns.server(server,port) dns.server(server,port)
end end
local default_port = {
http = 80,
https = 443,
}
local function hostname_port(host)
if host:find ".*:.*:" then
-- If host contains 2 or more ":", it's ipv6 address
local ipv6, port = host:match "^%[(.-)%]:(%d+)$"
if ipv6 then
return ipv6, port
else
return host
end
end
local hostname, port = host:match "(.-):(%d+)$"
if hostname then
return hostname, port
end
return host
end
local function check_protocol(host) local function check_protocol(host)
local protocol, hostname = host:match "^(%a+)://(.*)" local protocol, hostname = host:match "^(%a+)://(.*)"
if protocol then if protocol then
return string.lower(protocol), hostname protocol = string.lower(protocol)
else else
return "http", host protocol = "http"
hostname = host
end end
hostname, port = hostname_port(hostname)
return protocol, hostname, port or default_port[protocol] or error("Invalid protocol: " .. protocol)
end end
local SSLCTX_CLIENT = nil local SSLCTX_CLIENT = nil
@@ -56,44 +80,24 @@ local function gen_interface(protocol, fd, hostname)
end end
end end
local default_port = {
http = 80,
https = 443,
}
local function connect(host, timeout) local function connect(host, timeout)
local protocol, port local protocol, host, port = check_protocol(host)
protocol, host = check_protocol(host) local hostaddr = host
if not host:find ":%d+$" then if async_dns and host:find "^[^:]-%D$" then
port = default_port[protocol] or error("Invalid protocol: " .. protocol) -- if ipv6, contains colons
end -- if ipv4, end with a digit
if async_dns then local msg
local hostname hostaddr, msg = dns.resolve(host)
if port then -- without :%d+$ if not hostaddr then
-- if ipv6, contains colons error(string.format("%s dns resolve failed msg:%s", host, msg))
-- if ipv4, end with a digit
if host:find "^[^:]-[^%d]$" then
hostname = host
end
else -- with :%d+$ (port)
-- hostname string (ends with ":%d+") must begin with a substring that doesn't contain colon "[^:]"
-- and end with a character that is not a colon or a digit "[^%d%]]".
hostname, port = host:match "^([^:]-[^%d%]]):(%d+)$"
end end
if hostname then
local msg
host, msg = dns.resolve(hostname)
if not host then
error(string.format("%s dns resolve failed msg:%s", hostname, msg))
end
end
end end
local fd = socket.connect(host, port, timeout) local fd = socket.connect(hostaddr, port, timeout)
if not fd then if not fd then
error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, host, port, timeout)) error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, host, port, timeout))
end end
local interface = gen_interface(protocol, fd, hostname) local interface = gen_interface(protocol, fd, host)
if timeout then if timeout then
skynet.timeout(timeout, function() skynet.timeout(timeout, function()
if not interface.finish then if not interface.finish then