mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 12:28:21 +01:00
Adding support for bind before connect.
This commit is contained in:
parent
321c0c9b1f
commit
da30ec9c2e
49
src/http.lua
49
src/http.lua
@ -106,18 +106,44 @@ end
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
local metat = { __index = {} }
|
local metat = { __index = {} }
|
||||||
|
|
||||||
function _M.open(host, port, create)
|
local function _bindBeforeConnect(host, port, timeout)
|
||||||
|
-- Keep trying to get an ephemeral port, degrade gracefully.
|
||||||
|
-- Ports will free up as sockets move out of TIME_WAIT and
|
||||||
|
-- are released by the kernel (60 seconds or so).
|
||||||
|
local t = socket.gettime() + timeout
|
||||||
|
while socket.gettime() < t do
|
||||||
|
local c = socket.tcp()
|
||||||
|
c:settimeout(timeout)
|
||||||
|
c:setoption("reuseaddr", true)
|
||||||
|
c:bind("*", 0)
|
||||||
|
if c:connect(host, port) == 1 then
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
c:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M.open(host, opt)
|
||||||
|
local port = opt.port or _M.port
|
||||||
|
local timeout = opt.timeout or _M.TIMEOUT
|
||||||
|
if opt.bindBeforeConnect == true then
|
||||||
|
local c = socket.try(_bindBeforeConnect(host, port, timeout))
|
||||||
|
local h = base.setmetatable({ c = c }, metat)
|
||||||
|
h.try = socket.newtry(function() h:close() end)
|
||||||
|
return h
|
||||||
|
else
|
||||||
-- create socket with user connect function, or with default
|
-- create socket with user connect function, or with default
|
||||||
local c = socket.try((create or socket.tcp)())
|
local c = socket.try((create or socket.tcp)())
|
||||||
local h = base.setmetatable({ c = c }, metat)
|
local h = base.setmetatable({ c = c }, metat)
|
||||||
-- create finalized try
|
-- create finalized try
|
||||||
h.try = socket.newtry(function() h:close() end)
|
h.try = socket.newtry(function() h:close() end)
|
||||||
-- set timeout before connecting
|
-- set timeout before connecting
|
||||||
h.try(c:settimeout(_M.TIMEOUT))
|
h.try(c:settimeout(timeout))
|
||||||
h.try(c:connect(host, port or _M.PORT))
|
h.try(c:connect(host, port))
|
||||||
-- here everything worked
|
-- here everything worked
|
||||||
return h
|
return h
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function metat.__index:sendrequestline(method, uri)
|
function metat.__index:sendrequestline(method, uri)
|
||||||
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
|
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
|
||||||
@ -294,7 +320,7 @@ end
|
|||||||
-- we loop until we get what we want, or
|
-- we loop until we get what we want, or
|
||||||
-- until we are sure there is no way to get it
|
-- until we are sure there is no way to get it
|
||||||
local nreqt = adjustrequest(reqt)
|
local nreqt = adjustrequest(reqt)
|
||||||
local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
|
local h = _M.open(nreqt.host, nreqt)
|
||||||
-- send request line and headers
|
-- send request line and headers
|
||||||
h:sendrequestline(nreqt.method, nreqt.uri)
|
h:sendrequestline(nreqt.method, nreqt.uri)
|
||||||
h:sendheaders(nreqt.headers)
|
h:sendheaders(nreqt.headers)
|
||||||
@ -329,12 +355,21 @@ end
|
|||||||
return 1, code, headers, status
|
return 1, code, headers, status
|
||||||
end
|
end
|
||||||
|
|
||||||
local function srequest(u, b)
|
local function srequest(u, b, o)
|
||||||
local t = {}
|
local t = {}
|
||||||
local reqt = {
|
local reqt = {
|
||||||
url = u,
|
url = u,
|
||||||
sink = ltn12.sink.table(t)
|
sink = ltn12.sink.table(t)
|
||||||
}
|
}
|
||||||
|
if base.type(b) == "table" then
|
||||||
|
o = b
|
||||||
|
b = nil
|
||||||
|
end
|
||||||
|
if o ~= nil then
|
||||||
|
for k,v in pairs(o) do
|
||||||
|
reqt[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
if b then
|
if b then
|
||||||
reqt.source = ltn12.source.string(b)
|
reqt.source = ltn12.source.string(b)
|
||||||
reqt.headers = {
|
reqt.headers = {
|
||||||
@ -347,8 +382,8 @@ local function srequest(u, b)
|
|||||||
return table.concat(t), code, headers, status
|
return table.concat(t), code, headers, status
|
||||||
end
|
end
|
||||||
|
|
||||||
_M.request = socket.protect(function(reqt, body)
|
_M.request = socket.protect(function(reqt, body, opt)
|
||||||
if base.type(reqt) == "string" then return srequest(reqt, body)
|
if base.type(reqt) == "string" then return srequest(reqt, body, opt)
|
||||||
else return trequest(reqt) end
|
else return trequest(reqt) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user