@@ -11,21 +11,45 @@ local pairs = pairs
1111
1212local httpc = {}
1313
14-
1514local async_dns
1615
1716function httpc .dns (server ,port )
1817 async_dns = true
1918 dns .server (server ,port )
2019end
2120
21+ local default_port = {
22+ http = 80 ,
23+ https = 443 ,
24+ }
25+
26+ local function hostname_port (host )
27+ if host :find " .*:.*:" then
28+ -- If host contains 2 or more ":", it's ipv6 address
29+ local ipv6 , port = host :match " ^%[(.-)%]:(%d+)$"
30+ if ipv6 then
31+ return ipv6 , port
32+ else
33+ return host
34+ end
35+ end
36+ local hostname , port = host :match " (.-):(%d+)$"
37+ if hostname then
38+ return hostname , port
39+ end
40+ return host
41+ end
42+
2243local function check_protocol (host )
2344 local protocol , hostname = host :match " ^(%a+)://(.*)"
2445 if protocol then
25- return string.lower (protocol ), hostname
46+ protocol = string.lower (protocol )
2647 else
27- return " http" , host
48+ protocol = " http"
49+ hostname = host
2850 end
51+ hostname , port = hostname_port (hostname )
52+ return protocol , hostname , port or default_port [protocol ] or error (" Invalid protocol: " .. protocol )
2953end
3054
3155local SSLCTX_CLIENT = nil
@@ -56,44 +80,24 @@ local function gen_interface(protocol, fd, hostname)
5680 end
5781end
5882
59- local default_port = {
60- http = 80 ,
61- https = 443 ,
62- }
63-
6483local function connect (host , timeout )
65- local protocol , port
66- protocol , host = check_protocol (host )
67- if not host :find " :%d+$" then
68- port = default_port [protocol ] or error (" Invalid protocol: " .. protocol )
69- end
70- if async_dns then
71- local hostname
72- if port then -- without :%d+$
73- -- if ipv6, contains colons
74- -- if ipv4, end with a digit
75- if host :find " ^[^:]-[^%d]$" then
76- hostname = host
77- end
78- else -- with :%d+$ (port)
79- -- hostname string (ends with ":%d+") must begin with a substring that doesn't contain colon "[^:]"
80- -- and end with a character that is not a colon or a digit "[^%d%]]".
81- hostname , port = host :match " ^([^:]-[^%d%]]):(%d+)$"
84+ local protocol , host , port = check_protocol (host )
85+ local hostaddr = host
86+ if async_dns and host :find " ^[^:]-%D$" then
87+ -- if ipv6, contains colons
88+ -- if ipv4, end with a digit
89+ local msg
90+ hostaddr , msg = dns .resolve (host )
91+ if not hostaddr then
92+ error (string.format (" %s dns resolve failed msg:%s" , host , msg ))
8293 end
83- if hostname then
84- local msg
85- host , msg = dns .resolve (hostname )
86- if not host then
87- error (string.format (" %s dns resolve failed msg:%s" , hostname , msg ))
88- end
89- end
9094 end
9195
92- local fd = socket .connect (host , port , timeout )
96+ local fd = socket .connect (hostaddr , port , timeout )
9397 if not fd then
9498 error (string.format (" %s connect error host:%s, port:%s, timeout:%s" , protocol , host , port , timeout ))
9599 end
96- local interface = gen_interface (protocol , fd , hostname )
100+ local interface = gen_interface (protocol , fd , host )
97101 if timeout then
98102 skynet .timeout (timeout , function ()
99103 if not interface .finish then
0 commit comments