12 Commits

Author SHA1 Message Date
1531e31dfb Merge d78986f98d into 453a5207ed 2023-11-11 18:04:30 +00:00
d78986f98d Merge branch 'master' into Max1Truc/https-over-http-proxy-fix 2023-11-11 18:59:51 +01:00
453a5207ed style(docs): Trim trailing whitespace in HTML docs
Many editors remove these automatically anyway which makes opening and
editng the docs cause a bunch of noise. This is just to get the noise
out of the way in a style commit so it doesn't leak into other PRs
2023-11-11 08:07:38 +03:00
de359ea408 chore(core): Update version markers to last released version
Closes #401
2023-11-11 00:48:02 +03:00
c93f9154e1 feat(rockspec): Ship mbox parser with LuaRocks, already packaged in some distros
Closes #324
2023-11-11 00:44:22 +03:00
8a5368b659 Merge pull request #418 from alerque/url-empty-path 2023-11-09 14:11:33 +03:00
22b8202d70 fix(wsocket): Properly report CONNRESET (#81) 2023-11-09 14:00:09 +03:00
3a817a56eb fix(url): Avoid fragment being part of authority, allows parsing empty paths 2023-11-08 23:27:58 +03:00
7eaf648056 fix(url): Avoid query string being part of authority, allows parsing empty paths 2023-11-08 14:50:43 +03:00
bef62aeb50 fix(inet): Return port as number in getsockname (#392) 2023-11-08 14:29:06 +03:00
4c0677219f fix(http): use CONNECT for HTTPS over HTTP proxy 2022-08-27 20:52:28 +02:00
bd0f2ea49a fix(http): use the right protocol for proxies 2022-08-23 16:58:34 +02:00
11 changed files with 182 additions and 107 deletions

View File

@ -89,7 +89,7 @@ it should be easy to use LuaSocket. Just fire the interpreter and use the
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
> socket = require("socket")
> print(socket._VERSION)
--> LuaSocket 3.0.0
--> LuaSocket 3.1.0
</pre>
<p> Each module loads their dependencies automatically, so you only need to

View File

@ -69,6 +69,7 @@ local function make_plat(plat)
["socket.smtp"] = "src/smtp.lua",
ltn12 = "src/ltn12.lua",
socket = "src/socket.lua",
mbox = "src/mbox.lua",
mime = "src/mime.lua"
}
if plat == "unix"

View File

@ -1,7 +1,7 @@
#--------------------------------------------------------------------------
# Distribution makefile
#--------------------------------------------------------------------------
DIST = luasocket-3.0.0
DIST = luasocket-3.1.0
TEST = \
test/README \

View File

@ -203,8 +203,15 @@ end
-----------------------------------------------------------------------------
local function adjusturi(reqt)
local u = reqt
-- if there is a proxy, we need the full url. otherwise, just a part.
if not reqt.proxy and not _M.PROXY then
local proxy
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 = {
path = socket.try(reqt.path, "invalid path 'nil'"),
params = reqt.params,
@ -215,17 +222,7 @@ local function adjusturi(reqt)
return url.build(u)
end
local function adjustproxy(reqt)
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)
local function adjustheaders(reqt, https_connect)
-- default headers
local host = reqt.host
local port = tostring(reqt.port)
@ -244,9 +241,8 @@ local function adjustheaders(reqt)
url.unescape(reqt.password)))
end
-- if we have proxy authentication information, pass it along
local proxy = reqt.proxy or _M.PROXY
if proxy then
proxy = url.parse(proxy)
if reqt.proxy and (reqt.scheme == "http" or https_connect) then
local proxy = url.parse(reqt.proxy)
if proxy.user and proxy.password then
lower["proxy-authorization"] =
"Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
@ -259,6 +255,80 @@ local function adjustheaders(reqt)
return lower
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
local default = {
path ="/"
@ -268,6 +338,8 @@ local default = {
local function adjustrequest(reqt)
-- parse url if provided
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
for i,v in base.pairs(reqt) do nreqt[i] = v end
-- default to scheme particulars
@ -282,7 +354,7 @@ local function adjustrequest(reqt)
-- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt)
-- adjust headers in request
nreqt.headers = adjustheaders(nreqt)
nreqt.headers = adjustheaders(nreqt, false)
if nreqt.source
and not nreqt.headers["content-length"]
and not nreqt.headers["transfer-encoding"]
@ -290,8 +362,8 @@ local function adjustrequest(reqt)
nreqt.headers["transfer-encoding"] = "chunked"
end
-- ajust host and port if there is a proxy
nreqt.host, nreqt.port = adjustproxy(nreqt)
-- adjust host, port and create if there is a proxy
nreqt.host, nreqt.port, nreqt.create = adjustproxy(nreqt)
return nreqt
end

View File

@ -290,7 +290,7 @@ int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
return 2;
}
lua_pushstring(L, name);
lua_pushstring(L, port);
lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10));
switch (family) {
case AF_INET: lua_pushliteral(L, "inet"); break;
case AF_INET6: lua_pushliteral(L, "inet6"); break;

View File

@ -10,7 +10,7 @@
/*-------------------------------------------------------------------------* \
* Current socket library version
\*-------------------------------------------------------------------------*/
#define LUASOCKET_VERSION "LuaSocket 3.0.0"
#define LUASOCKET_VERSION "LuaSocket 3.1.0"
#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab"
/*-------------------------------------------------------------------------*\

View File

@ -272,7 +272,7 @@ SOCKET_win64=wsocket.obj
#
SO=$(SO_$(PLAT))
O=$(O_$(PLAT))
SOCKET_V=3.0.0
SOCKET_V=3.1.0
MIME_V=1.0.3
SOCKET_SO=socket-$(SOCKET_V).$(SO)
MIME_SO=mime-$(MIME_V).$(SO)

View File

@ -152,7 +152,7 @@ function _M.parse(url, default)
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
function(s) parsed.scheme = s; return "" end)
-- get authority
url = string.gsub(url, "^//([^/]*)", function(n)
url = string.gsub(url, "^//([^/%?#]*)", function(n)
parsed.authority = n
return ""
end)

View File

@ -262,6 +262,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
if (err != WSAEWOULDBLOCK) {
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
prev = err;
continue;
}
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
@ -291,6 +292,7 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
if (err != WSAEWOULDBLOCK) {
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
prev = err;
continue;
}
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}