From 312943c6a0cff4a20975065bc01251850af5218c Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 13 Apr 2017 15:32:54 +0800 Subject: [PATCH] connect timeout, see #611 --- lualib/http/httpc.lua | 2 +- lualib/http/sockethelper.lua | 24 ++++++++++++++++++++++-- test/testhttp.lua | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lualib/http/httpc.lua b/lualib/http/httpc.lua index 16a52823..43a44e19 100644 --- a/lualib/http/httpc.lua +++ b/lualib/http/httpc.lua @@ -99,7 +99,7 @@ function httpc.request(method, host, url, recvheader, header, content) if async_dns and not hostname:match(".*%d+$") then hostname = dns.resolve(hostname) end - local fd = socket.connect(hostname, port) + local fd = socket.connect(hostname, port, timeout) local finish if timeout then skynet.timeout(timeout, function() diff --git a/lualib/http/sockethelper.lua b/lualib/http/sockethelper.lua index 735da45d..0d8e80fb 100644 --- a/lualib/http/sockethelper.lua +++ b/lualib/http/sockethelper.lua @@ -1,4 +1,5 @@ local socket = require "socket" +local skynet = require "skynet" local readbytes = socket.read local writebytes = socket.write @@ -66,8 +67,27 @@ function sockethelper.writefunc(fd) end end -function sockethelper.connect(host, port) - local fd = socket.open(host, port) +function sockethelper.connect(host, port, timeout) + local fd + if timeout then + local drop_fd + -- asynchronous connect + skynet.fork(function() + fd = socket.open(host, port) + if drop_fd then + -- sockethelper.connect already return, and raise socket_error + socket.close(fd) + end + end) + skynet.sleep(timeout) + if not fd then + -- not connect yet + drop_fd = true + end + else + -- block connect + fd = socket.open(host, port) + end if fd then return fd end diff --git a/test/testhttp.lua b/test/testhttp.lua index e66d6c19..4098b629 100644 --- a/test/testhttp.lua +++ b/test/testhttp.lua @@ -2,7 +2,7 @@ local skynet = require "skynet" local httpc = require "http.httpc" local dns = require "dns" -skynet.start(function() +local function main() httpc.dns() -- set dns server httpc.timeout = 100 -- set timeout 1 second print("GET baidu.com") @@ -21,6 +21,9 @@ skynet.start(function() print(string.format("GET %s (baidu.com)", ip)) local status, body = httpc.get("baidu.com", "/", respheader, { host = "baidu.com" }) print(status) +end +skynet.start(function() + print(pcall(main)) skynet.exit() end)