mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
add https client and server support by bios
This commit is contained in:
@@ -8,9 +8,9 @@ local table = table
|
||||
|
||||
local httpc = {}
|
||||
|
||||
local function request(fd, method, host, url, recvheader, header, content)
|
||||
local read = socket.readfunc(fd)
|
||||
local write = socket.writefunc(fd)
|
||||
local function request(interface, method, host, url, recvheader, header, content)
|
||||
local read = interface.read
|
||||
local write = interface.write
|
||||
local header_content = ""
|
||||
if header then
|
||||
if not header.host then
|
||||
@@ -74,7 +74,7 @@ local function request(fd, method, host, url, recvheader, header, content)
|
||||
end
|
||||
else
|
||||
-- no content-length, read all
|
||||
body = body .. socket.readall(fd)
|
||||
body = body .. interface.readall()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -88,11 +88,60 @@ function httpc.dns(server,port)
|
||||
dns.server(server,port)
|
||||
end
|
||||
|
||||
|
||||
local function check_protocol(host)
|
||||
local protocol = host:match("^[Hh][Tt][Tt][Pp][Ss]?://")
|
||||
if protocol then
|
||||
host = string.gsub(host, "^"..protocol, "")
|
||||
protocol = string.lower(protocol)
|
||||
if protocol == "https://" then
|
||||
return "https", host
|
||||
elseif protocol == "http://" then
|
||||
return "http", host
|
||||
else
|
||||
error(string.format("Invalid protocol: %s", protocol))
|
||||
end
|
||||
else
|
||||
return "http", host
|
||||
end
|
||||
end
|
||||
|
||||
local SSLCTX_CLIENT = nil
|
||||
local function gen_interface(protocol, fd)
|
||||
if protocol == "http" then
|
||||
return {
|
||||
init = nil,
|
||||
close = nil,
|
||||
read = socket.readfunc(fd),
|
||||
write = socket.writefunc(fd),
|
||||
readall = function ()
|
||||
return socket.readall(fd)
|
||||
end,
|
||||
}
|
||||
elseif protocol == "https" then
|
||||
local tls = require "http.tlshelper"
|
||||
SSLCTX_CLIENT = SSLCTX_CLIENT or tls.newctx()
|
||||
local tls_ctx = tls.newtls("client", SSLCTX_CLIENT)
|
||||
return {
|
||||
init = tls.init_requestfunc(fd, tls_ctx),
|
||||
close = tls.closefunc(tls_ctx),
|
||||
read = tls.readfunc(fd, tls_ctx),
|
||||
write = tls.writefunc(fd, tls_ctx),
|
||||
readall = tls.readallfunc(fd, tls_ctx),
|
||||
}
|
||||
else
|
||||
error(string.format("Invalid protocol: %s", protocol))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function httpc.request(method, host, url, recvheader, header, content)
|
||||
local protocol
|
||||
local timeout = httpc.timeout -- get httpc.timeout before any blocked api
|
||||
protocol, host = check_protocol(host)
|
||||
local hostname, port = host:match"([^:]+):?(%d*)$"
|
||||
if port == "" then
|
||||
port = 80
|
||||
port = protocol=="http" and 80 or protocol=="https" and 443
|
||||
else
|
||||
port = tonumber(port)
|
||||
end
|
||||
@@ -101,20 +150,31 @@ function httpc.request(method, host, url, recvheader, header, content)
|
||||
end
|
||||
local fd = socket.connect(hostname, port, timeout)
|
||||
if not fd then
|
||||
error(string.format("http connect error host:%s, port:%s, timeout:%s", hostname, port, timeout))
|
||||
error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, hostname, port, timeout))
|
||||
return
|
||||
end
|
||||
-- print("protocol hostname port", protocol, hostname, port)
|
||||
local interface = gen_interface(protocol, fd)
|
||||
local finish
|
||||
if timeout then
|
||||
skynet.timeout(timeout, function()
|
||||
if not finish then
|
||||
socket.shutdown(fd) -- shutdown the socket fd, need close later.
|
||||
if interface.close then
|
||||
interface.close()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
local ok , statuscode, body = pcall(request, fd,method, host, url, recvheader, header, content)
|
||||
if interface.init then
|
||||
interface.init()
|
||||
end
|
||||
local ok , statuscode, body = pcall(request, interface, method, host, url, recvheader, header, content)
|
||||
finish = true
|
||||
socket.close(fd)
|
||||
if interface.close then
|
||||
interface.close()
|
||||
end
|
||||
if ok then
|
||||
return statuscode, body
|
||||
else
|
||||
|
||||
94
lualib/http/tlshelper.lua
Normal file
94
lualib/http/tlshelper.lua
Normal file
@@ -0,0 +1,94 @@
|
||||
local socket = require "http.sockethelper"
|
||||
local c = require "ltls.c"
|
||||
|
||||
local tlshelper = {}
|
||||
|
||||
function tlshelper.init_requestfunc(fd, tls_ctx)
|
||||
local readfunc = socket.readfunc(fd)
|
||||
local writefunc = socket.writefunc(fd)
|
||||
return function ()
|
||||
local ds1 = tls_ctx:handshake()
|
||||
writefunc(ds1)
|
||||
while not tls_ctx:finished() do
|
||||
local ds2 = readfunc()
|
||||
local ds3 = tls_ctx:handshake(ds2)
|
||||
if ds3 then
|
||||
writefunc(ds3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function tlshelper.init_responsefunc(fd, tls_ctx)
|
||||
local readfunc = socket.readfunc(fd)
|
||||
local writefunc = socket.writefunc(fd)
|
||||
return function ()
|
||||
while not tls_ctx:finished() do
|
||||
local ds1 = readfunc()
|
||||
local ds2 = tls_ctx:handshake(ds1)
|
||||
if ds2 then
|
||||
writefunc(ds2)
|
||||
end
|
||||
end
|
||||
local ds3 = tls_ctx:write()
|
||||
writefunc(ds3)
|
||||
end
|
||||
end
|
||||
|
||||
function tlshelper.closefunc(tls_ctx)
|
||||
return function ()
|
||||
tls_ctx:close()
|
||||
end
|
||||
end
|
||||
|
||||
function tlshelper.readfunc(fd, tls_ctx)
|
||||
local readfunc = socket.readfunc(fd)
|
||||
local read_buff = ""
|
||||
return function (sz)
|
||||
if not sz then
|
||||
local s = ""
|
||||
if #read_buff == 0 then
|
||||
local ds = readfunc(sz)
|
||||
s = tls_ctx:read(ds)
|
||||
end
|
||||
return read_buff .. s
|
||||
else
|
||||
while #read_buff < sz do
|
||||
local ds = readfunc()
|
||||
local s = tls_ctx:read(ds)
|
||||
read_buff = read_buff .. s
|
||||
end
|
||||
local s = string.sub(read_buff, 1, sz)
|
||||
read_buff = string.sub(read_buff, sz+1, #read_buff)
|
||||
return s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tlshelper.writefunc(fd, tls_ctx)
|
||||
local writefunc = socket.writefunc(fd)
|
||||
return function (s)
|
||||
local ds = tls_ctx:write(s)
|
||||
return writefunc(ds)
|
||||
end
|
||||
end
|
||||
|
||||
function tlshelper.readallfunc(fd, tls_ctx)
|
||||
local readfunc = socket.readfunc(fd)
|
||||
return function ()
|
||||
local ds = socket.readall(fd)
|
||||
local s = tls_ctx:read(ds)
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
function tlshelper.newctx()
|
||||
return c.newctx()
|
||||
end
|
||||
|
||||
function tlshelper.newtls(method, ssl_ctx)
|
||||
return c.newtls(method, ssl_ctx)
|
||||
end
|
||||
|
||||
return tlshelper
|
||||
Reference in New Issue
Block a user