mirror of
https://github.com/lunarmodules/luasocket.git
synced 2025-05-01 12:46:45 +02:00
Compare commits
8 Commits
f8c257866c
...
cd22215520
Author | SHA1 | Date | |
---|---|---|---|
|
cd22215520 | ||
|
0f37af645c | ||
|
9c6195ea62 | ||
|
708e50f8e6 | ||
|
0bc8c56043 | ||
|
f741a88b80 | ||
|
4c0677219f | ||
|
bd0f2ea49a |
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@ -13,22 +13,27 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
luaVersion: [ "5.4", "5.3", "5.2", "5.1", "luajit", "luajit-openresty" ]
|
luaVersion: [ "5.4", "5.3", "5.2", "5.1", "luajit", "luajit-openresty" ]
|
||||||
platform: [ "ubuntu-20.04", "macos-11" ] # "windows-2022" not supported by gh-actions-lua
|
platform: [ "ubuntu-20.04", "macos-11", "windows-2022" ]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
- name: Setup ’msvc’
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
if: ${{ !startsWith(matrix.luaVersion, 'luajit') }}
|
||||||
- name: Setup ‘lua’
|
- name: Setup ‘lua’
|
||||||
uses: leafo/gh-actions-lua@v9
|
uses: leso-kn/gh-actions-lua@v11-staging
|
||||||
with:
|
with:
|
||||||
luaVersion: ${{ matrix.luaVersion }}
|
luaVersion: ${{ matrix.luaVersion }}
|
||||||
- name: Setup ‘luarocks’
|
- name: Setup ‘luarocks’
|
||||||
uses: leafo/gh-actions-luarocks@v4
|
uses: hishamhm/gh-actions-luarocks@master
|
||||||
- name: Make and install
|
- name: Make and install
|
||||||
run: |
|
run: |
|
||||||
export DEBUG=DEBUG
|
|
||||||
luarocks make -- luasocket-scm-3.rockspec
|
luarocks make -- luasocket-scm-3.rockspec
|
||||||
|
env:
|
||||||
|
DEBUG: DEBUG
|
||||||
- name: Run regression tests
|
- name: Run regression tests
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cd test
|
cd test
|
||||||
lua hello.lua
|
lua hello.lua
|
||||||
|
110
src/http.lua
110
src/http.lua
@ -203,8 +203,15 @@ end
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
local function adjusturi(reqt)
|
local function adjusturi(reqt)
|
||||||
local u = reqt
|
local u = reqt
|
||||||
-- if there is a proxy, we need the full url. otherwise, just a part.
|
local proxy
|
||||||
if not reqt.proxy and not _M.PROXY then
|
if reqt.proxy then
|
||||||
|
proxy = url.parse(reqt.proxy)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We just need the path if there's no proxy,
|
||||||
|
-- or if we use https over an http proxy.
|
||||||
|
-- Otherwise, we use a full url
|
||||||
|
if not proxy or (reqt.scheme == "https" and proxy.scheme == "http") then
|
||||||
u = {
|
u = {
|
||||||
path = socket.try(reqt.path, "invalid path 'nil'"),
|
path = socket.try(reqt.path, "invalid path 'nil'"),
|
||||||
params = reqt.params,
|
params = reqt.params,
|
||||||
@ -215,17 +222,7 @@ local function adjusturi(reqt)
|
|||||||
return url.build(u)
|
return url.build(u)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function adjustproxy(reqt)
|
local function adjustheaders(reqt, https_connect)
|
||||||
local proxy = reqt.proxy or _M.PROXY
|
|
||||||
if proxy then
|
|
||||||
proxy = url.parse(proxy)
|
|
||||||
return proxy.host, proxy.port or 3128
|
|
||||||
else
|
|
||||||
return reqt.host, reqt.port
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function adjustheaders(reqt)
|
|
||||||
-- default headers
|
-- default headers
|
||||||
local host = reqt.host
|
local host = reqt.host
|
||||||
local port = tostring(reqt.port)
|
local port = tostring(reqt.port)
|
||||||
@ -244,9 +241,8 @@ local function adjustheaders(reqt)
|
|||||||
url.unescape(reqt.password)))
|
url.unescape(reqt.password)))
|
||||||
end
|
end
|
||||||
-- if we have proxy authentication information, pass it along
|
-- if we have proxy authentication information, pass it along
|
||||||
local proxy = reqt.proxy or _M.PROXY
|
if reqt.proxy and (reqt.scheme == "http" or https_connect) then
|
||||||
if proxy then
|
local proxy = url.parse(reqt.proxy)
|
||||||
proxy = url.parse(proxy)
|
|
||||||
if proxy.user and proxy.password then
|
if proxy.user and proxy.password then
|
||||||
lower["proxy-authorization"] =
|
lower["proxy-authorization"] =
|
||||||
"Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
|
"Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
|
||||||
@ -259,6 +255,80 @@ local function adjustheaders(reqt)
|
|||||||
return lower
|
return lower
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function reg(conn)
|
||||||
|
local mt = getmetatable(conn.sock).__index
|
||||||
|
for name, method in pairs(mt) do
|
||||||
|
if type(method) == "function" then
|
||||||
|
conn[name] = function (self, ...)
|
||||||
|
return method(self.sock, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function proxy_connect_create(params, proxy)
|
||||||
|
-- Copied and adapted from luasec's https.lua
|
||||||
|
-- in function ssl.http.tcp()
|
||||||
|
|
||||||
|
local ssl = assert(
|
||||||
|
require("ssl"), 'LuaSocket: LuaSec not found')
|
||||||
|
local https = assert(
|
||||||
|
require("ssl.https"), 'LuaSocket: LuaSec not found')
|
||||||
|
|
||||||
|
-- Force client mode
|
||||||
|
params.mode = "client"
|
||||||
|
-- 'create' function
|
||||||
|
return function ()
|
||||||
|
local conn = {}
|
||||||
|
conn.proxy_sock = _M.open(proxy.host, proxy.port, proxy.create)
|
||||||
|
local try = conn.proxy_sock.try
|
||||||
|
|
||||||
|
function conn:settimeout(...)
|
||||||
|
return self.proxy_sock.c:settimeout(https.TIMEOUT)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Wrap the underlying connection function
|
||||||
|
function conn:connect(host, port)
|
||||||
|
conn.proxy_sock:sendrequestline("CONNECT", host .. ":" .. tostring(port))
|
||||||
|
conn.proxy_sock:sendheaders(adjustheaders(proxy, true))
|
||||||
|
|
||||||
|
local code, _ = conn.proxy_sock:receivestatusline()
|
||||||
|
try(code == 200 or nil)
|
||||||
|
|
||||||
|
self.sock = try(ssl.wrap(self.proxy_sock.c, params))
|
||||||
|
self.sock:sni(host)
|
||||||
|
self.sock:settimeout(https.TIMEOUT)
|
||||||
|
try(self.sock:dohandshake())
|
||||||
|
reg(self)
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Close the underlying socket
|
||||||
|
function conn:close()
|
||||||
|
conn.proxy_sock:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
return conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function adjustproxy(reqt)
|
||||||
|
if reqt.proxy then
|
||||||
|
local proxy = url.parse(reqt.proxy)
|
||||||
|
proxy.port = proxy.port or 3128
|
||||||
|
proxy.create = SCHEMES[proxy.scheme].create(reqt)
|
||||||
|
|
||||||
|
if reqt.scheme == "https" and proxy.scheme == "http" then
|
||||||
|
local wrapped_create = proxy_connect_create(reqt, proxy)
|
||||||
|
return reqt.host, reqt.port, wrapped_create
|
||||||
|
else
|
||||||
|
return proxy.host, proxy.port, proxy.create
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return reqt.host, reqt.port, reqt.create
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- default url parts
|
-- default url parts
|
||||||
local default = {
|
local default = {
|
||||||
path ="/"
|
path ="/"
|
||||||
@ -268,6 +338,8 @@ local default = {
|
|||||||
local function adjustrequest(reqt)
|
local function adjustrequest(reqt)
|
||||||
-- parse url if provided
|
-- parse url if provided
|
||||||
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
||||||
|
-- get global proxy
|
||||||
|
nreqt.proxy = reqt.proxy or _M.PROXY
|
||||||
-- explicit components override url
|
-- explicit components override url
|
||||||
for i,v in base.pairs(reqt) do nreqt[i] = v end
|
for i,v in base.pairs(reqt) do nreqt[i] = v end
|
||||||
-- default to scheme particulars
|
-- default to scheme particulars
|
||||||
@ -282,7 +354,7 @@ local function adjustrequest(reqt)
|
|||||||
-- compute uri if user hasn't overriden
|
-- compute uri if user hasn't overriden
|
||||||
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
||||||
-- adjust headers in request
|
-- adjust headers in request
|
||||||
nreqt.headers = adjustheaders(nreqt)
|
nreqt.headers = adjustheaders(nreqt, false)
|
||||||
if nreqt.source
|
if nreqt.source
|
||||||
and not nreqt.headers["content-length"]
|
and not nreqt.headers["content-length"]
|
||||||
and not nreqt.headers["transfer-encoding"]
|
and not nreqt.headers["transfer-encoding"]
|
||||||
@ -290,8 +362,8 @@ local function adjustrequest(reqt)
|
|||||||
nreqt.headers["transfer-encoding"] = "chunked"
|
nreqt.headers["transfer-encoding"] = "chunked"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ajust host and port if there is a proxy
|
-- adjust host, port and create if there is a proxy
|
||||||
nreqt.host, nreqt.port = adjustproxy(nreqt)
|
nreqt.host, nreqt.port, nreqt.create = adjustproxy(nreqt)
|
||||||
return nreqt
|
return nreqt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,6 +54,33 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps)
|
|||||||
return opt->func(L, ps);
|
return opt->func(L, ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------*/
|
||||||
|
/* binds socket to network interface */
|
||||||
|
int opt_set_bindtodevice(lua_State *L, p_socket ps)
|
||||||
|
{
|
||||||
|
#ifndef SO_BINDTODEVICE
|
||||||
|
return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system");
|
||||||
|
#else
|
||||||
|
const char *dev = luaL_checkstring(L, 3);
|
||||||
|
return opt_set(L, ps, SOL_SOCKET, SO_BINDTODEVICE, (char*)dev, strlen(dev)+1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt_get_bindtodevice(lua_State *L, p_socket ps)
|
||||||
|
{
|
||||||
|
#ifndef SO_BINDTODEVICE
|
||||||
|
return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system");
|
||||||
|
#else
|
||||||
|
char dev[IFNAMSIZ];
|
||||||
|
int len = sizeof(dev);
|
||||||
|
int err = opt_get(L, ps, SOL_SOCKET, SO_BINDTODEVICE, &dev, &len);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
lua_pushstring(L, dev);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
/* enables reuse of local address */
|
/* enables reuse of local address */
|
||||||
int opt_set_reuseaddr(lua_State *L, p_socket ps)
|
int opt_set_reuseaddr(lua_State *L, p_socket ps)
|
||||||
|
@ -53,6 +53,9 @@ int opt_get_tcp_keepintvl(lua_State *L, p_socket ps);
|
|||||||
int opt_set_tcp_defer_accept(lua_State *L, p_socket ps);
|
int opt_set_tcp_defer_accept(lua_State *L, p_socket ps);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int opt_set_bindtodevice(lua_State *L, p_socket ps);
|
||||||
|
int opt_get_bindtodevice(lua_State *L, p_socket ps);
|
||||||
|
|
||||||
int opt_set_keepalive(lua_State *L, p_socket ps);
|
int opt_set_keepalive(lua_State *L, p_socket ps);
|
||||||
int opt_get_keepalive(lua_State *L, p_socket ps);
|
int opt_get_keepalive(lua_State *L, p_socket ps);
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ static luaL_Reg tcp_methods[] = {
|
|||||||
|
|
||||||
/* socket option handlers */
|
/* socket option handlers */
|
||||||
static t_opt optget[] = {
|
static t_opt optget[] = {
|
||||||
|
{"bindtodevice", opt_get_bindtodevice},
|
||||||
{"keepalive", opt_get_keepalive},
|
{"keepalive", opt_get_keepalive},
|
||||||
{"reuseaddr", opt_get_reuseaddr},
|
{"reuseaddr", opt_get_reuseaddr},
|
||||||
{"reuseport", opt_get_reuseport},
|
{"reuseport", opt_get_reuseport},
|
||||||
@ -92,6 +93,7 @@ static t_opt optget[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static t_opt optset[] = {
|
static t_opt optset[] = {
|
||||||
|
{"bindtodevice", opt_set_bindtodevice},
|
||||||
{"keepalive", opt_set_keepalive},
|
{"keepalive", opt_set_keepalive},
|
||||||
{"reuseaddr", opt_set_reuseaddr},
|
{"reuseaddr", opt_set_reuseaddr},
|
||||||
{"reuseport", opt_set_reuseport},
|
{"reuseport", opt_set_reuseport},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user