From 5b4b9158799293eeaf8439d40a7845b5b0a5e125 Mon Sep 17 00:00:00 2001
From: Diego Nehab
Date: Fri, 4 Mar 2016 16:16:41 -0300
Subject: Remove global PORT. Fix https redirect.
---
src/http.lua | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index 45ffa15..d6bcc91 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -23,11 +23,14 @@ local _M = socket.http
-----------------------------------------------------------------------------
-- connection timeout in seconds
_M.TIMEOUT = 60
--- default port for document retrieval
-_M.PORT = 80
-- user agent field sent in request
_M.USERAGENT = socket._VERSION
+-- supported schemes
+local SCHEMES = { ["http"] = true }
+-- default port for document retrieval
+local PORT = 80
+
-----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed
-----------------------------------------------------------------------------
@@ -114,7 +117,7 @@ function _M.open(host, port, create)
h.try = socket.newtry(function() h:close() end)
-- set timeout before connecting
h.try(c:settimeout(_M.TIMEOUT))
- h.try(c:connect(host, port or _M.PORT))
+ h.try(c:connect(host, port or PORT))
-- here everything worked
return h
end
@@ -218,7 +221,7 @@ local function adjustheaders(reqt)
}
-- if we have authentication information, pass it along
if reqt.user and reqt.password then
- lower["authorization"] =
+ lower["authorization"] =
"Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
end
-- if we have proxy authentication information, pass it along
@@ -226,7 +229,7 @@ local function adjustheaders(reqt)
if proxy then
proxy = url.parse(proxy)
if proxy.user and proxy.password then
- lower["proxy-authorization"] =
+ lower["proxy-authorization"] =
"Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
end
end
@@ -240,7 +243,7 @@ end
-- default url parts
local default = {
host = "",
- port = _M.PORT,
+ port = PORT,
path ="/",
scheme = "http"
}
@@ -250,9 +253,10 @@ local function adjustrequest(reqt)
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
-- explicit components override url
for i,v in base.pairs(reqt) do nreqt[i] = v end
- if nreqt.port == "" then nreqt.port = 80 end
- socket.try(nreqt.host and nreqt.host ~= "",
- "invalid host '" .. base.tostring(nreqt.host) .. "'")
+ if nreqt.port == "" then nreqt.port = PORT end
+ if not (nreqt.host and nreqt.host ~= "") then
+ socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'")
+ end
-- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt)
-- adjust headers in request
@@ -263,9 +267,13 @@ local function adjustrequest(reqt)
end
local function shouldredirect(reqt, code, headers)
- return headers.location and
- string.gsub(headers.location, "%s", "") ~= "" and
- (reqt.redirect ~= false) and
+ local location = headers.location
+ if not location then return false end
+ location = string.gsub(location, "%s", "")
+ if location == "" then return false end
+ local scheme = string.match(location, "^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then return false end
+ return (reqt.redirect ~= false) and
(code == 301 or code == 302 or code == 303 or code == 307) and
(not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
and (not reqt.nredirects or reqt.nredirects < 5)
@@ -289,10 +297,10 @@ local trequest, tredirect
source = reqt.source,
sink = reqt.sink,
headers = reqt.headers,
- proxy = reqt.proxy,
+ proxy = reqt.proxy,
nredirects = (reqt.nredirects or 0) + 1,
create = reqt.create
- }
+ }
-- pass location header back as a hint we redirected
headers = headers or {}
headers.location = headers.location or location
@@ -309,7 +317,7 @@ end
h:sendheaders(nreqt.headers)
-- if there is a body, send it
if nreqt.source then
- h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
+ h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
end
local code, status = h:receivestatusline()
-- if it is an HTTP/0.9 server, simply get the body and we are done
@@ -319,13 +327,13 @@ end
end
local headers
-- ignore any 100-continue messages
- while code == 100 do
+ while code == 100 do
headers = h:receiveheaders()
code, status = h:receivestatusline()
end
headers = h:receiveheaders()
-- at this point we should have a honest reply from the server
- -- we can't redirect if we already used the source, so we report the error
+ -- we can't redirect if we already used the source, so we report the error
if shouldredirect(nreqt, code, headers) and not nreqt.source then
h:close()
return tredirect(reqt, headers.location)
--
cgit v1.2.3-55-g6feb
From 916b548240b1513410b13f964d80f329aec9c13a Mon Sep 17 00:00:00 2001
From: Diego Nehab
Date: Mon, 7 Mar 2016 01:30:30 -0300
Subject: Family agostic FTP and expose HTTP/FTP url parsing
---
src/ftp.lua | 67 ++++++++++++++++++++++++++++++++++++++++++--------------
src/http.lua | 17 ++++++++++----
src/tp.lua | 10 ++++++++-
test/ftptest.lua | 34 ++++++++++++++++++----------
4 files changed, 96 insertions(+), 32 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/ftp.lua b/src/ftp.lua
index e0c3cae..11798ad 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -51,7 +51,7 @@ end
function metat.__index:pasvconnect()
self.data = self.try(socket.tcp())
self.try(self.data:settimeout(_M.TIMEOUT))
- self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
+ self.try(self.data:connect(self.pasvt.address, self.pasvt.port))
end
function metat.__index:login(user, password)
@@ -71,32 +71,65 @@ function metat.__index:pasv()
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
self.try(a and b and c and d and p1 and p2, reply)
self.pasvt = {
- ip = string.format("%d.%d.%d.%d", a, b, c, d),
+ address = string.format("%d.%d.%d.%d", a, b, c, d),
port = p1*256 + p2
}
if self.server then
self.server:close()
self.server = nil
end
- return self.pasvt.ip, self.pasvt.port
+ return self.pasvt.address, self.pasvt.port
end
-function metat.__index:port(ip, port)
+function metat.__index:epsv()
+ self.try(self.tp:command("epsv"))
+ local code, reply = self.try(self.tp:check("229"))
+ local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d, prt, address, port = string.match(reply, pattern)
+ self.try(port, "invalid epsv response")
+ self.pasvt = {
+ address = self.tp:getpeername(),
+ port = port
+ }
+ if self.server then
+ self.server:close()
+ self.server = nil
+ end
+ return self.pasvt.address, self.pasvt.port
+end
+
+
+function metat.__index:port(address, port)
self.pasvt = nil
- if not ip then
- ip, port = self.try(self.tp:getcontrol():getsockname())
- self.server = self.try(socket.bind(ip, 0))
- ip, port = self.try(self.server:getsockname())
+ if not address then
+ address, port = self.try(self.tp:getsockname())
+ self.server = self.try(socket.bind(address, 0))
+ address, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(_M.TIMEOUT))
end
local pl = math.mod(port, 256)
local ph = (port - pl)/256
- local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",")
+ local arg = string.gsub(string.format("%s,%d,%d", address, ph, pl), "%.", ",")
self.try(self.tp:command("port", arg))
self.try(self.tp:check("2.."))
return 1
end
+function metat.__index:eprt(family, address, port)
+ self.pasvt = nil
+ if not address then
+ address, port = self.try(self.tp:getsockname())
+ self.server = self.try(socket.bind(address, 0))
+ address, port = self.try(self.server:getsockname())
+ self.try(self.server:settimeout(_M.TIMEOUT))
+ end
+ local arg = string.format("|%s|%s|%d|", family, address, port)
+ self.try(self.tp:command("eprt", arg))
+ self.try(self.tp:check("2.."))
+ return 1
+end
+
+
function metat.__index:send(sendt)
self.try(self.pasvt or self.server, "need port or pasv first")
-- if there is a pasvt table, we already sent a PASV command
@@ -110,12 +143,12 @@ function metat.__index:send(sendt)
-- send the transfer command and check the reply
self.try(self.tp:command(command, argument))
local code, reply = self.try(self.tp:check{"2..", "1.."})
- -- if there is not a a pasvt table, then there is a server
+ -- if there is not a pasvt table, then there is a server
-- and we already sent a PORT command
if not self.pasvt then self:portconnect() end
-- get the sink, source and step for the transfer
local step = sendt.step or ltn12.pump.step
- local readt = {self.tp.c}
+ local readt = { self.tp }
local checkstep = function(src, snk)
-- check status in control connection while downloading
local readyt = socket.select(readt, nil, 0)
@@ -207,7 +240,7 @@ local function tput(putt)
f:greet()
f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end
- f:pasv()
+ f:epsv()
local sent = f:send(putt)
f:quit()
f:close()
@@ -219,7 +252,7 @@ local default = {
scheme = "ftp"
}
-local function parse(u)
+local function genericform(u)
local t = socket.try(url.parse(u, default))
socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
socket.try(t.host, "missing hostname")
@@ -232,8 +265,10 @@ local function parse(u)
return t
end
+_M.genericform = genericform
+
local function sput(u, body)
- local putt = parse(u)
+ local putt = genericform(u)
putt.source = ltn12.source.string(body)
return tput(putt)
end
@@ -250,14 +285,14 @@ local function tget(gett)
f:greet()
f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end
- f:pasv()
+ f:epsv()
f:receive(gett)
f:quit()
return f:close()
end
local function sget(u)
- local gett = parse(u)
+ local gett = genericform(u)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)
diff --git a/src/http.lua b/src/http.lua
index d6bcc91..f2fff01 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -346,11 +346,13 @@ end
return 1, code, headers, status
end
-local function srequest(u, b)
+-- turns an url and a body into a generic request
+local function genericform(u, b)
local t = {}
local reqt = {
url = u,
- sink = ltn12.sink.table(t)
+ sink = ltn12.sink.table(t),
+ target = t
}
if b then
reqt.source = ltn12.source.string(b)
@@ -360,8 +362,15 @@ local function srequest(u, b)
}
reqt.method = "POST"
end
- local code, headers, status = socket.skip(1, trequest(reqt))
- return table.concat(t), code, headers, status
+ return reqt
+end
+
+_M.genericform = genericform
+
+local function srequest(u, b)
+ local reqt = genericform(u, b)
+ local _, code, headers, status = trequest(reqt)
+ return table.concat(reqt.target), code, headers, status
end
_M.request = socket.protect(function(reqt, body)
diff --git a/src/tp.lua b/src/tp.lua
index 328cbab..b8ebc56 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -46,6 +46,14 @@ end
-- metatable for sock object
local metat = { __index = {} }
+function metat.__index:getpeername()
+ return self.c:getpeername()
+end
+
+function metat.__index:getsockname()
+ return self.c:getpeername()
+end
+
function metat.__index:check(ok)
local code, reply = get_reply(self.c)
if not code then return nil, reply end
@@ -123,4 +131,4 @@ function _M.connect(host, port, timeout, create)
return base.setmetatable({c = c}, metat)
end
-return _M
\ No newline at end of file
+return _M
diff --git a/test/ftptest.lua b/test/ftptest.lua
index fb13326..3ea0d39 100644
--- a/test/ftptest.lua
+++ b/test/ftptest.lua
@@ -3,19 +3,31 @@ local ftp = require("socket.ftp")
local url = require("socket.url")
local ltn12 = require("ltn12")
+-- use dscl to create user "luasocket" with password "password"
+-- with home in /Users/diego/luasocket/test/ftp
+-- with group com.apple.access_ftp
+-- with shell set to /sbin/nologin
+-- set /etc/ftpchroot to chroot luasocket
+-- must set group com.apple.access_ftp on user _ftp (for anonymous access)
+-- copy index.html to /var/empty/pub (home of user ftp)
+-- start ftp server with
+-- sudo -s launchctl load -w /System/Library/LaunchDaemons/ftp.plist
+-- copy index.html to /Users/diego/luasocket/test/ftp
+-- stop with
+-- sudo -s launchctl unload -w /System/Library/LaunchDaemons/ftp.plist
+
-- override protection to make sure we see all errors
--socket.protect = function(s) return s end
dofile("testsupport.lua")
-local host, port, index_file, index, back, err, ret
+local host = host or "localhost"
+local port, index_file, index, back, err, ret
local t = socket.gettime()
-host = host or "localhost"
index_file = "index.html"
-
-- a function that returns a directory listing
local function nlst(u)
local t = {}
@@ -55,27 +67,27 @@ assert(not err and back == index, err)
print("ok")
io.write("erasing before upload: ")
-ret, err = dele("ftp://luasocket:pedrovian@" .. host .. "/index.up.html")
-if not ret then print(err)
+ret, err = dele("ftp://luasocket:password@" .. host .. "/index.up.html")
+if not ret then print(err)
else print("ok") end
io.write("testing upload: ")
-ret, err = ftp.put("ftp://luasocket:pedrovian@" .. host .. "/index.up.html;type=i", index)
+ret, err = ftp.put("ftp://luasocket:password@" .. host .. "/index.up.html;type=i", index)
assert(ret and not err, err)
print("ok")
io.write("downloading uploaded file: ")
-back, err = ftp.get("ftp://luasocket:pedrovian@" .. host .. "/index.up.html;type=i")
+back, err = ftp.get("ftp://luasocket:password@" .. host .. "/index.up.html;type=i")
assert(ret and not err and index == back, err)
print("ok")
io.write("erasing after upload/download: ")
-ret, err = dele("ftp://luasocket:pedrovian@" .. host .. "/index.up.html")
-assert(ret and not err, err)
+ret, err = dele("ftp://luasocket:password@" .. host .. "/index.up.html")
+assert(ret and not err, err)
print("ok")
io.write("testing weird-character translation: ")
-back, err = ftp.get("ftp://luasocket:pedrovian@" .. host .. "/%23%3f;type=i")
+back, err = ftp.get("ftp://luasocket:password@" .. host .. "/%23%3f;type=i")
assert(not err and back == index, err)
print("ok")
@@ -84,7 +96,7 @@ local back = {}
ret, err = ftp.get{
url = "//stupid:mistake@" .. host .. "/index.html",
user = "luasocket",
- password = "pedrovian",
+ password = "password",
type = "i",
sink = ltn12.sink.table(back)
}
--
cgit v1.2.3-55-g6feb
From b9f6fd215a8f522733caedcb4d6d6b0c6e55103e Mon Sep 17 00:00:00 2001
From: Okash Khawaja
Date: Tue, 12 Apr 2016 00:04:21 +0100
Subject: URL-decode user password before adding to authorization header.
---
src/http.lua | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index f2fff01..a386165 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -222,7 +222,8 @@ local function adjustheaders(reqt)
-- if we have authentication information, pass it along
if reqt.user and reqt.password then
lower["authorization"] =
- "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
+ "Basic " .. (mime.b64(reqt.user .. ":" ..
+ url.unescape(reqt.password)))
end
-- if we have proxy authentication information, pass it along
local proxy = reqt.proxy or _M.PROXY
--
cgit v1.2.3-55-g6feb
From 4a3504612cda28f25ab777db94bfeab55e081e16 Mon Sep 17 00:00:00 2001
From: xyida <522918670@qq.com>
Date: Thu, 26 Apr 2018 16:39:29 +0800
Subject: Fixed an issue that was mistaken for HTTP 0.9 when timeout
---
src/http.lua | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index a386165..79a931c 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -147,10 +147,15 @@ function metat.__index:sendbody(headers, source, step)
end
function metat.__index:receivestatusline()
- local status = self.try(self.c:receive(5))
+ local status,ec = self.try(self.c:receive(5))
-- identify HTTP/0.9 responses, which do not contain a status line
-- this is just a heuristic, but is what the RFC recommends
- if status ~= "HTTP/" then return nil, status end
+ if status ~= "HTTP/" then
+ if ec == "timeout" then
+ return 408
+ end
+ return nil, status
+ end
-- otherwise proceed reading a status line
status = self.try(self.c:receive("*l", status))
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
@@ -325,6 +330,8 @@ end
if not code then
h:receive09body(status, nreqt.sink, nreqt.step)
return 1, 200
+ elseif code == 408 then
+ return 1, code
end
local headers
-- ignore any 100-continue messages
--
cgit v1.2.3-55-g6feb
From 686f2ce8222077e13ecdf9cf09f43f0b1878a737 Mon Sep 17 00:00:00 2001
From: "E. Westbrook"
Date: Thu, 12 Jul 2018 11:07:20 -0600
Subject: http.lua: if default for scheme, omit port number in "Host:" header
---
src/http.lua | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index a386165..6b26a0a 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -27,9 +27,13 @@ _M.TIMEOUT = 60
_M.USERAGENT = socket._VERSION
-- supported schemes
-local SCHEMES = { ["http"] = true }
--- default port for document retrieval
-local PORT = 80
+local SCHEMES = {
+ http = { port = 80 }
+ , https = { port = 443 }}
+
+-- default scheme and port for document retrieval
+local SCHEME = 'http'
+local PORT = SCHEMES[SCHEME].port
-----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed
@@ -212,10 +216,14 @@ end
local function adjustheaders(reqt)
-- default headers
- local host = string.gsub(reqt.authority, "^.-@", "")
+ local headhost = reqt.host
+ local headport = tostring(reqt.port)
+ local schemeport = tostring(SCHEMES[reqt.scheme].port)
+ if headport ~= schemeport then
+ headhost = headhost .. ':' .. headport end
local lower = {
["user-agent"] = _M.USERAGENT,
- ["host"] = host,
+ ["host"] = headhost,
["connection"] = "close, TE",
["te"] = "trailers"
}
@@ -246,7 +254,7 @@ local default = {
host = "",
port = PORT,
path ="/",
- scheme = "http"
+ scheme = SCHEME
}
local function adjustrequest(reqt)
--
cgit v1.2.3-55-g6feb
From 09ff9b650c3567c91eed62f4dd571729df2dedd4 Mon Sep 17 00:00:00 2001
From: "E. Westbrook"
Date: Fri, 13 Jul 2018 12:52:26 -0600
Subject: http.lua: allow override of hard-coded 5 max redirects
---
doc/http.html | 8 +++++---
src/http.lua | 5 ++++-
2 files changed, 9 insertions(+), 4 deletions(-)
(limited to 'src/http.lua')
diff --git a/doc/http.html b/doc/http.html
index 3b7a8b1..78f785a 100644
--- a/doc/http.html
+++ b/doc/http.html
@@ -135,7 +135,8 @@ http.request{
[step = LTN12 pump step,]
[proxy = string,]
[redirect = boolean,]
- [create = function]
+ [create = function,]
+ [maxredirects = number]
}
@@ -185,6 +186,7 @@ Defaults to the LTN12 pump.step function.
function from automatically following 301 or 302 server redirect messages;
create: An optional function to be used instead of
socket.tcp when the communications socket is created.
+maxredirects: An optional number specifying the maximum number of redirects to follow. Defaults to 5 if not specified. A boolean false value means no maximum (unlimited).
@@ -324,8 +326,8 @@ r, c = http.request {
-Last modified by Diego Nehab on
-Thu Apr 20 00:25:26 EDT 2006
+Last modified by Eric Westbrook on
+Sat Feb 23 19:09:42 UTC 2019
diff --git a/src/http.lua b/src/http.lua
index a386165..8bda0d8 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -277,7 +277,9 @@ local function shouldredirect(reqt, code, headers)
return (reqt.redirect ~= false) and
(code == 301 or code == 302 or code == 303 or code == 307) and
(not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
- and (not reqt.nredirects or reqt.nredirects < 5)
+ and ((false == reqt.maxredirects)
+ or ((reqt.nredirects or 0)
+ < (reqt.maxredirects or 5)))
end
local function shouldreceivebody(reqt, code)
@@ -299,6 +301,7 @@ local trequest, tredirect
sink = reqt.sink,
headers = reqt.headers,
proxy = reqt.proxy,
+ maxredirects = reqt.maxredirects,
nredirects = (reqt.nredirects or 0) + 1,
create = reqt.create
}
--
cgit v1.2.3-55-g6feb
From e587800164d5d6fb75fe34166978438c949db215 Mon Sep 17 00:00:00 2001
From: "E. Westbrook"
Date: Thu, 12 Jul 2018 01:10:11 -0600
Subject: socket.http.request(): simultaneous support for http and https URL
schemes, with caller-adjustable scheme-to-transport mappings (default
"socket.http" and "ssl.https")
---
src/http.lua | 56 +++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 19 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index 19b4dd3..25eb25d 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -26,15 +26,20 @@ _M.TIMEOUT = 60
-- user agent field sent in request
_M.USERAGENT = socket._VERSION
--- supported schemes
+-- supported schemes and their particulars
local SCHEMES = {
- http = { port = 80 }
- , https = { port = 443 }}
+ http = {
+ port = 80
+ , create = function(t)
+ return socket.tcp end }
+ , https = {
+ port = 443
+ , create = function(t)
+ return require("ssl.https").tcp(t) end }}
-- default scheme and port for document retrieval
local SCHEME = 'http'
local PORT = SCHEMES[SCHEME].port
-
-----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed
-----------------------------------------------------------------------------
@@ -115,13 +120,13 @@ local metat = { __index = {} }
function _M.open(host, port, create)
-- create socket with user connect function, or with default
- local c = socket.try((create or socket.tcp)())
+ local c = socket.try(create())
local h = base.setmetatable({ c = c }, metat)
-- create finalized try
h.try = socket.newtry(function() h:close() end)
-- set timeout before connecting
h.try(c:settimeout(_M.TIMEOUT))
- h.try(c:connect(host, port or PORT))
+ h.try(c:connect(host, port))
-- here everything worked
return h
end
@@ -221,14 +226,13 @@ end
local function adjustheaders(reqt)
-- default headers
- local headhost = reqt.host
- local headport = tostring(reqt.port)
- local schemeport = tostring(SCHEMES[reqt.scheme].port)
- if headport ~= schemeport then
- headhost = headhost .. ':' .. headport end
+ local host = reqt.host
+ local port = tostring(reqt.port)
+ if port ~= tostring(SCHEMES[reqt.scheme].port) then
+ host = host .. ':' .. port end
local lower = {
["user-agent"] = _M.USERAGENT,
- ["host"] = headhost,
+ ["host"] = host,
["connection"] = "close, TE",
["te"] = "trailers"
}
@@ -267,8 +271,13 @@ local function adjustrequest(reqt)
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
-- explicit components override url
for i,v in base.pairs(reqt) do nreqt[i] = v end
- if nreqt.port == "" then nreqt.port = PORT end
- if not (nreqt.host and nreqt.host ~= "") then
+ -- default to scheme particulars
+ local schemedefs, host, port, method
+ = SCHEMES[nreqt.scheme], nreqt.host, nreqt.port, nreqt.method
+ if not nreqt.create then nreqt.create = schemedefs.create(nreqt) end
+ if not (port and port ~= '') then nreqt.port = schemedefs.port end
+ if not (method and method ~= '') then nreqt.method = 'GET' end
+ if not (host and host ~= "") then
socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'")
end
-- compute uri if user hasn't overriden
@@ -285,8 +294,10 @@ local function shouldredirect(reqt, code, headers)
if not location then return false end
location = string.gsub(location, "%s", "")
if location == "" then return false end
- local scheme = string.match(location, "^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then return false end
+ local scheme = url.parse(location).scheme
+ if scheme and (not SCHEMES[scheme]) then return false end
+ -- avoid https downgrades
+ if ('https' == reqt.scheme) and ('https' ~= scheme) then return false end
return (reqt.redirect ~= false) and
(code == 301 or code == 302 or code == 303 or code == 307) and
(not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
@@ -306,10 +317,16 @@ end
local trequest, tredirect
--[[local]] function tredirect(reqt, location)
+ -- the RFC says the redirect URL has to be absolute, but some
+ -- servers do not respect that
+ local newurl = url.absolute(reqt.url, location)
+ -- if switching schemes, reset port and create function
+ if url.parse(newurl).scheme ~= reqt.scheme then
+ reqt.port = nil
+ reqt.create = nil end
+ -- make new request
local result, code, headers, status = trequest {
- -- the RFC says the redirect URL has to be absolute, but some
- -- servers do not respect that
- url = url.absolute(reqt.url, location),
+ url = newurl,
source = reqt.source,
sink = reqt.sink,
headers = reqt.headers,
@@ -397,4 +414,5 @@ _M.request = socket.protect(function(reqt, body)
else return trequest(reqt) end
end)
+_M.schemes = SCHEMES
return _M
--
cgit v1.2.3-55-g6feb
From 2a467001f6dbadf447a79dfbd036f32b6a82ce05 Mon Sep 17 00:00:00 2001
From: "E. Westbrook"
Date: Sun, 24 Feb 2019 16:24:42 -0700
Subject: http.lua: Error informatively if insufficient LuaSec support
---
src/http.lua | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index 25eb25d..2fa5a26 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -35,7 +35,11 @@ local SCHEMES = {
, https = {
port = 443
, create = function(t)
- return require("ssl.https").tcp(t) end }}
+ local https = assert(
+ require("ssl.https"), 'LuaSocket: LuaSec not found')
+ local tcp = assert(
+ https.tcp, 'LuaSocket: Function tcp() not available from LuaSec')
+ return tcp(t) end }}
-- default scheme and port for document retrieval
local SCHEME = 'http'
--
cgit v1.2.3-55-g6feb
From 297f9d0277ca4c93a5bd4306e0d31a4a98940089 Mon Sep 17 00:00:00 2001
From: "E. Westbrook"
Date: Thu, 28 Feb 2019 18:40:30 -0700
Subject: bugfix: http.lua multischeme change that got dropped during PR
conflict resolution
---
src/http.lua | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index 2fa5a26..6a3416e 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -264,10 +264,8 @@ end
-- default url parts
local default = {
- host = "",
- port = PORT,
- path ="/",
- scheme = SCHEME
+ path ="/"
+ , scheme = "http"
}
local function adjustrequest(reqt)
--
cgit v1.2.3-55-g6feb
From 601ad8d59f11d7180015d0ecfb9d0a8d67f6f5c1 Mon Sep 17 00:00:00 2001
From: Thijs Schreijer
Date: Fri, 18 Mar 2022 12:12:39 +0100
Subject: refactor: Address issues raised by linter
---
etc/cookie.lua | 22 ++++-----
etc/get.lua | 2 +-
gem/ex11.lua | 4 +-
gem/ex3.lua | 2 +-
gem/ex4.lua | 2 +-
samples/cddb.lua | 2 +-
src/ftp.lua | 14 +++---
src/http.lua | 11 ++---
src/ltn12.lua | 3 +-
src/mbox.lua | 13 +++---
src/mime.lua | 12 +----
src/url.lua | 6 +--
test/ltn12test.lua | 24 +++++-----
test/mimetest.lua | 46 +++++++++---------
test/smtptest.lua | 20 ++++----
test/test_socket_error.lua | 2 +-
test/testmesg.lua | 14 +++---
test/testsupport.lua | 2 +-
test/urltest.lua | 114 ++++++++++++++++++++++-----------------------
test/utestclnt.lua | 68 +++++++++++++--------------
test/utestsrvr.lua | 2 +-
21 files changed, 187 insertions(+), 198 deletions(-)
(limited to 'src/http.lua')
diff --git a/etc/cookie.lua b/etc/cookie.lua
index 4adb403..fec10a1 100644
--- a/etc/cookie.lua
+++ b/etc/cookie.lua
@@ -5,7 +5,7 @@ local ltn12 = require"ltn12"
local token_class = '[^%c%s%(%)%<%>%@%,%;%:%\\%"%/%[%]%?%=%{%}]'
-local function unquote(t, quoted)
+local function unquote(t, quoted)
local n = string.match(t, "%$(%d+)$")
if n then n = tonumber(n) end
if quoted[n] then return quoted[n]
@@ -14,19 +14,19 @@ end
local function parse_set_cookie(c, quoted, cookie_table)
c = c .. ";$last=last;"
- local _, __, n, v, i = string.find(c, "(" .. token_class ..
+ local _, _, n, v, i = string.find(c, "(" .. token_class ..
"+)%s*=%s*(.-)%s*;%s*()")
local cookie = {
- name = n,
- value = unquote(v, quoted),
+ name = n,
+ value = unquote(v, quoted),
attributes = {}
}
while 1 do
- _, __, n, v, i = string.find(c, "(" .. token_class ..
+ _, _, n, v, i = string.find(c, "(" .. token_class ..
"+)%s*=?%s*(.-)%s*;%s*()", i)
if not n or n == "$last" then break end
cookie.attributes[#cookie.attributes+1] = {
- name = n,
+ name = n,
value = unquote(v, quoted)
}
end
@@ -46,8 +46,8 @@ local function split_set_cookie(s, cookie_table)
-- split into individual cookies
i = 1
while 1 do
- local _, __, cookie, next_token
- _, __, cookie, i, next_token = string.find(s, "(.-)%s*%,%s*()(" ..
+ local _, _, cookie, next_token
+ _, _, cookie, i, next_token = string.find(s, "(.-)%s*%,%s*()(" ..
token_class .. "+)%s*=", i)
if not next_token then break end
parse_set_cookie(cookie, quoted, cookie_table)
@@ -62,12 +62,12 @@ local function quote(s)
end
local _empty = {}
-local function build_cookies(cookies)
+local function build_cookies(cookies)
s = ""
for i,v in ipairs(cookies or _empty) do
if v.name then
s = s .. v.name
- if v.value and v.value ~= "" then
+ if v.value and v.value ~= "" then
s = s .. '=' .. quote(v.value)
end
end
@@ -83,6 +83,6 @@ local function build_cookies(cookies)
end
if i < #cookies then s = s .. ", " end
end
- return s
+ return s
end
diff --git a/etc/get.lua b/etc/get.lua
index 9edc235..d53c465 100644
--- a/etc/get.lua
+++ b/etc/get.lua
@@ -71,7 +71,7 @@ function stats(size)
local current = socket.gettime()
if chunk then
-- total bytes received
- got = got + string.len(chunk)
+ got = got + string.len(chunk)
-- not enough time for estimate
if current - last > 1 then
io.stderr:write("\r", gauge(got, current - start, size))
diff --git a/gem/ex11.lua b/gem/ex11.lua
index 1cbf01f..79c99af 100644
--- a/gem/ex11.lua
+++ b/gem/ex11.lua
@@ -1,7 +1,7 @@
local input = source.chain(
- source.file(io.open("input.bin", "rb")),
+ source.file(io.open("input.bin", "rb")),
encode("base64"))
local output = sink.chain(
- wrap(76),
+ wrap(76),
sink.file(io.open("output.b64", "w")))
pump.all(input, output)
diff --git a/gem/ex3.lua b/gem/ex3.lua
index a43fefa..60b4423 100644
--- a/gem/ex3.lua
+++ b/gem/ex3.lua
@@ -7,7 +7,7 @@ local function chainpair(f1, f2)
end
function filter.chain(...)
- local f = select(1, ...)
+ local f = select(1, ...)
for i = 2, select('#', ...) do
f = chainpair(f, select(i, ...))
end
diff --git a/gem/ex4.lua b/gem/ex4.lua
index c670e0e..c48b77e 100644
--- a/gem/ex4.lua
+++ b/gem/ex4.lua
@@ -1,4 +1,4 @@
-local qp = filter.chain(normalize(CRLF), encode("quoted-printable"),
+local qp = filter.chain(normalize(CRLF), encode("quoted-printable"),
wrap("quoted-printable"))
local input = source.chain(source.file(io.stdin), qp)
local output = sink.file(io.stdout)
diff --git a/samples/cddb.lua b/samples/cddb.lua
index 49a1871..59d5a44 100644
--- a/samples/cddb.lua
+++ b/samples/cddb.lua
@@ -26,7 +26,7 @@ function parse(body)
data[key] = value
end
end
- return data, code, message
+ return data, code, message
end
local host = socket.dns.gethostname()
diff --git a/src/ftp.lua b/src/ftp.lua
index bd528ca..0ebc508 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -56,7 +56,7 @@ end
function metat.__index:login(user, password)
self.try(self.tp:command("user", user or _M.USER))
- local code, reply = self.try(self.tp:check{"2..", 331})
+ local code, _ = self.try(self.tp:check{"2..", 331})
if code == 331 then
self.try(self.tp:command("pass", password or _M.PASSWORD))
self.try(self.tp:check("2.."))
@@ -66,7 +66,7 @@ end
function metat.__index:pasv()
self.try(self.tp:command("pasv"))
- local code, reply = self.try(self.tp:check("2.."))
+ local _, reply = self.try(self.tp:check("2.."))
local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
self.try(a and b and c and d and p1 and p2, reply)
@@ -83,9 +83,9 @@ end
function metat.__index:epsv()
self.try(self.tp:command("epsv"))
- local code, reply = self.try(self.tp:check("229"))
+ local _, reply = self.try(self.tp:check("229"))
local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)"
- local d, prt, address, port = string.match(reply, pattern)
+ local _, _, _, port = string.match(reply, pattern)
self.try(port, "invalid epsv response")
self.pasvt = {
address = self.tp:getpeername(),
@@ -102,7 +102,7 @@ end
function metat.__index:port(address, port)
self.pasvt = nil
if not address then
- address, port = self.try(self.tp:getsockname())
+ address = self.try(self.tp:getsockname())
self.server = self.try(socket.bind(address, 0))
address, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(_M.TIMEOUT))
@@ -118,7 +118,7 @@ end
function metat.__index:eprt(family, address, port)
self.pasvt = nil
if not address then
- address, port = self.try(self.tp:getsockname())
+ address = self.try(self.tp:getsockname())
self.server = self.try(socket.bind(address, 0))
address, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(_M.TIMEOUT))
@@ -142,7 +142,7 @@ function metat.__index:send(sendt)
local command = sendt.command or "stor"
-- send the transfer command and check the reply
self.try(self.tp:command(command, argument))
- local code, reply = self.try(self.tp:check{"2..", "1.."})
+ local code, _ = self.try(self.tp:check{"2..", "1.."})
-- if there is not a pasvt table, then there is a server
-- and we already sent a PORT command
if not self.pasvt then self:portconnect() end
diff --git a/src/http.lua b/src/http.lua
index 6a3416e..e3a1742 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -41,9 +41,6 @@ local SCHEMES = {
https.tcp, 'LuaSocket: Function tcp() not available from LuaSec')
return tcp(t) end }}
--- default scheme and port for document retrieval
-local SCHEME = 'http'
-local PORT = SCHEMES[SCHEME].port
-----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed
-----------------------------------------------------------------------------
@@ -92,7 +89,7 @@ socket.sourcet["http-chunked"] = function(sock, headers)
-- was it the last chunk?
if size > 0 then
-- if not, get chunk and skip terminating CRLF
- local chunk, err, part = sock:receive(size)
+ local chunk, err, _ = sock:receive(size)
if chunk then sock:receive() end
return chunk, err
else
@@ -166,8 +163,8 @@ function metat.__index:receivestatusline()
if status ~= "HTTP/" then
if ec == "timeout" then
return 408
- end
- return nil, status
+ end
+ return nil, status
end
-- otherwise proceed reading a status line
status = self.try(self.c:receive("*l", status))
@@ -366,7 +363,7 @@ end
local headers
-- ignore any 100-continue messages
while code == 100 do
- headers = h:receiveheaders()
+ h:receiveheaders()
code, status = h:receivestatusline()
end
headers = h:receiveheaders()
diff --git a/src/ltn12.lua b/src/ltn12.lua
index afa735d..f1e05e1 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -13,7 +13,7 @@ local unpack = unpack or table.unpack
local base = _G
local _M = {}
if module then -- heuristic for exporting a global package table
- ltn12 = _M
+ ltn12 = _M -- luacheck: ignore
end
local filter,source,sink,pump = {},{},{},{}
@@ -23,7 +23,6 @@ _M.sink = sink
_M.pump = pump
local unpack = unpack or table.unpack
-local select = base.select
-- 2048 seems to be better in windows...
_M.BLOCKSIZE = 2048
diff --git a/src/mbox.lua b/src/mbox.lua
index ed9e781..12823b0 100644
--- a/src/mbox.lua
+++ b/src/mbox.lua
@@ -1,8 +1,8 @@
local _M = {}
if module then
- mbox = _M
-end
+ mbox = _M -- luacheck: ignore
+end
function _M.split_message(message_s)
local message = {}
@@ -29,7 +29,7 @@ end
function _M.parse_header(header_s)
header_s = string.gsub(header_s, "\n[ ]+", " ")
header_s = string.gsub(header_s, "\n+", "")
- local _, __, name, value = string.find(header_s, "([^%s:]-):%s*(.*)")
+ local _, _, name, value = string.find(header_s, "([^%s:]-):%s*(.*)")
return name, value
end
@@ -49,9 +49,9 @@ function _M.parse_headers(headers_s)
end
function _M.parse_from(from)
- local _, __, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>")
+ local _, _, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>")
if not address then
- _, __, address = string.find(from, "%s*(.+)%s*")
+ _, _, address = string.find(from, "%s*(.+)%s*")
end
name = name or ""
address = address or ""
@@ -63,7 +63,8 @@ end
function _M.split_mbox(mbox_s)
local mbox = {}
mbox_s = string.gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n"
- local nj, i, j = 1, 1, 1
+ local nj, i
+ local j = 1
while 1 do
i, nj = string.find(mbox_s, "\n\nFrom .-\n", j)
if not i then break end
diff --git a/src/mime.lua b/src/mime.lua
index d3abac5..93539de 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -10,7 +10,6 @@
local base = _G
local ltn12 = require("ltn12")
local mime = require("mime.core")
-local string = require("string")
local _M = mime
-- encode, decode and wrap algorithm tables
@@ -18,7 +17,7 @@ local encodet, decodet, wrapt = {},{},{}
_M.encodet = encodet
_M.decodet = decodet
-_M.wrapt = wrapt
+_M.wrapt = wrapt
-- creates a function that chooses a filter by name from a given table
local function choose(table)
@@ -27,7 +26,7 @@ local function choose(table)
name, opt1, opt2 = "default", name, opt1
end
local f = table[name or "nil"]
- if not f then
+ if not f then
base.error("unknown key (" .. base.tostring(name) .. ")", 3)
else return f(opt1, opt2) end
end
@@ -52,13 +51,6 @@ decodet['quoted-printable'] = function()
return ltn12.filter.cycle(_M.unqp, "")
end
-local function format(chunk)
- if chunk then
- if chunk == "" then return "''"
- else return string.len(chunk) end
- else return "nil" end
-end
-
-- define the line-wrap filters
wrapt['text'] = function(length)
length = length or 76
diff --git a/src/url.lua b/src/url.lua
index 0a3a80a..8e0dc5c 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -179,9 +179,9 @@ function _M.parse(url, default)
function(u) parsed.userinfo = u; return "" end)
authority = string.gsub(authority, ":([^:%]]*)$",
function(p) parsed.port = p; return "" end)
- if authority ~= "" then
+ if authority ~= "" then
-- IPv6?
- parsed.host = string.match(authority, "^%[(.+)%]$") or authority
+ parsed.host = string.match(authority, "^%[(.+)%]$") or authority
end
local userinfo = parsed.userinfo
if not userinfo then return parsed end
@@ -264,7 +264,7 @@ function _M.absolute(base_url, relative_url)
relative_parsed.query = base_parsed.query
end
end
- else
+ else
relative_parsed.path = absolute_path(base_parsed.path or "",
relative_parsed.path)
end
diff --git a/test/ltn12test.lua b/test/ltn12test.lua
index e7d368d..0cafbc9 100644
--- a/test/ltn12test.lua
+++ b/test/ltn12test.lua
@@ -38,7 +38,7 @@ local function named(f, name)
end
--------------------------------
-local function split(size)
+local function split(size)
local buffer = ""
local last_out = ""
local last_in = ""
@@ -50,12 +50,12 @@ local function split(size)
return last_out
end
return function(chunk, done)
- if done then
- return not last_in and not last_out
+ if done then
+ return not last_in and not last_out
end
-- check if argument is consistent with state
if not chunk then
- if last_in and last_in ~= "" and last_out ~= "" then
+ if last_in and last_in ~= "" and last_out ~= "" then
error("nil chunk following data chunk", 2)
end
if not last_out then error("extra nil chunk", 2) end
@@ -67,8 +67,8 @@ local function split(size)
return output(chunk)
else
if not last_in then error("data chunk following nil chunk", 2) end
- if last_in ~= "" and last_out ~= "" then
- error("data chunk following data chunk", 2)
+ if last_in ~= "" and last_out ~= "" then
+ error("data chunk following data chunk", 2)
end
buffer = chunk
return output(chunk)
@@ -85,7 +85,7 @@ local function format(chunk)
end
--------------------------------
-local function merge(size)
+local function merge(size)
local buffer = ""
local last_out = ""
local last_in = ""
@@ -102,12 +102,12 @@ local function merge(size)
return last_out
end
return function(chunk, done)
- if done then
- return not last_in and not last_out
+ if done then
+ return not last_in and not last_out
end
-- check if argument is consistent with state
if not chunk then
- if last_in and last_in ~= "" and last_out ~= "" then
+ if last_in and last_in ~= "" and last_out ~= "" then
error("nil chunk following data chunk", 2)
end
if not last_out then error("extra nil chunk", 2) end
@@ -119,8 +119,8 @@ local function merge(size)
return output(chunk)
else
if not last_in then error("data chunk following nil chunk", 2) end
- if last_in ~= "" and last_out ~= "" then
- error("data chunk following data chunk", 2)
+ if last_in ~= "" and last_out ~= "" then
+ error("data chunk following data chunk", 2)
end
buffer = buffer .. chunk
return output(chunk)
diff --git a/test/mimetest.lua b/test/mimetest.lua
index f5b3747..a3c89ac 100644
--- a/test/mimetest.lua
+++ b/test/mimetest.lua
@@ -15,27 +15,27 @@ local eb64test = "b64test.bin2"
local db64test = "b64test.bin3"
--- from Machado de Assis, "A Mão e a Rosa"
+-- from Machado de Assis, "A M�o e a Rosa"
local mao = [[
- Cursavam estes dois moços a academia de S. Paulo, estando
- Luís Alves no quarto ano e Estêvão no terceiro.
- Conheceram-se na academia, e ficaram amigos íntimos, tanto
- quanto podiam sê-lo dois espíritos diferentes, ou talvez por
- isso mesmo que o eram. Estêvão, dotado de extrema
- sensibilidade, e não menor fraqueza de ânimo, afetuoso e
- bom, não daquela bondade varonil, que é apanágio de uma alma
- forte, mas dessa outra bondade mole e de cera, que vai à
- mercê de todas as circunstâncias, tinha, além de tudo isso,
- o infortúnio de trazer ainda sobre o nariz os óculos
- cor-de-rosa de suas virginais ilusões. Luís Alves via bem
- com os olhos da cara. Não era mau rapaz, mas tinha o seu
- grão de egoísmo, e se não era incapaz de afeições, sabia
- regê-las, moderá-las, e sobretudo guiá-las ao seu próprio
+ Cursavam estes dois mo�os a academia de S. Paulo, estando
+ Lu�s Alves no quarto ano e Est�v�o no terceiro.
+ Conheceram-se na academia, e ficaram amigos �ntimos, tanto
+ quanto podiam s�-lo dois esp�ritos diferentes, ou talvez por
+ isso mesmo que o eram. Est�v�o, dotado de extrema
+ sensibilidade, e n�o menor fraqueza de �nimo, afetuoso e
+ bom, n�o daquela bondade varonil, que � apan�gio de uma alma
+ forte, mas dessa outra bondade mole e de cera, que vai �
+ merc� de todas as circunst�ncias, tinha, al�m de tudo isso,
+ o infort�nio de trazer ainda sobre o nariz os �culos
+ cor-de-rosa de suas virginais ilus�es. Lu�s Alves via bem
+ com os olhos da cara. N�o era mau rapaz, mas tinha o seu
+ gr�o de ego�smo, e se n�o era incapaz de afei��es, sabia
+ reg�-las, moder�-las, e sobretudo gui�-las ao seu pr�prio
interesse. Entre estes dois homens travara-se amizade
- íntima, nascida para um na simpatia, para outro no costume.
+ �ntima, nascida para um na simpatia, para outro no costume.
Eram eles os naturais confidentes um do outro, com a
- diferença que Luís Alves dava menos do que recebia, e, ainda
- assim, nem tudo o que dava exprimia grande confiança.
+ diferen�a que Lu�s Alves dava menos do que recebia, e, ainda
+ assim, nem tudo o que dava exprimia grande confian�a.
]]
local function random(handle, io_err)
@@ -44,8 +44,8 @@ local function random(handle, io_err)
if not handle then error("source is empty!", 2) end
local len = math.random(0, 1024)
local chunk = handle:read(len)
- if not chunk then
- handle:close()
+ if not chunk then
+ handle:close()
handle = nil
end
return chunk
@@ -62,7 +62,7 @@ local what = nil
local function transform(input, output, filter)
local source = random(io.open(input, "rb"))
local sink = ltn12.sink.file(io.open(output, "wb"))
- if what then
+ if what then
sink = ltn12.sink.chain(filter, sink)
else
source = ltn12.source.chain(source, filter)
@@ -147,7 +147,7 @@ local function create_qptest()
f:write(' ',string.char(32))
end
f:write("\r\n")
-
+
f:close()
end
@@ -157,7 +157,7 @@ local function cleanup_qptest()
os.remove(dqptest)
end
--- create test file
+-- create test file
local function create_b64test()
local f = assert(io.open(b64test, "wb"))
local t = {}
diff --git a/test/smtptest.lua b/test/smtptest.lua
index b5380ff..9d06054 100644
--- a/test/smtptest.lua
+++ b/test/smtptest.lua
@@ -27,8 +27,8 @@ local total = function()
end
local similar = function(s1, s2)
- return
- string.lower(string.gsub(s1, "%s", "")) ==
+ return
+ string.lower(string.gsub(s1, "%s", "")) ==
string.lower(string.gsub(s2, "%s", ""))
end
@@ -40,9 +40,9 @@ end
local readfile = function(name)
local f = io.open(name, "r")
- if not f then
+ if not f then
fail("unable to open file!")
- return nil
+ return nil
end
local s = f:read("*a")
f:close()
@@ -52,7 +52,7 @@ end
local empty = function()
for i,v in ipairs(files) do
local f = io.open(v, "w")
- if not f then
+ if not f then
fail("unable to open file!")
end
f:close()
@@ -116,8 +116,8 @@ local wait = function(sentinel, n)
while 1 do
local mbox = parse(get())
if n == #mbox then break end
- if socket.time() - sentinel.time > 50 then
- to = 1
+ if socket.time() - sentinel.time > 50 then
+ to = 1
break
end
socket.sleep(1)
@@ -132,7 +132,7 @@ local stuffed_body = [[
This message body needs to be
stuffed because it has a dot
.
-by itself on a line.
+by itself on a line.
Otherwise the mailer would
think that the dot
.
@@ -219,7 +219,7 @@ else print("ok") end
io.write("testing invalid from: ")
local ret, err = socket.smtp.mail{
- from = ' " " (( _ * ',
+ from = ' " " (( _ * ',
rcpt = rcpt,
}
if ret or not err then fail("wrong error message")
@@ -227,7 +227,7 @@ else print(err) end
io.write("testing no rcpt: ")
local ret, err = socket.smtp.mail{
- from = from,
+ from = from,
}
if ret or not err then fail("wrong error message")
else print(err) end
diff --git a/test/test_socket_error.lua b/test/test_socket_error.lua
index bda6408..1b4b601 100644
--- a/test/test_socket_error.lua
+++ b/test/test_socket_error.lua
@@ -19,7 +19,7 @@ for i = 1, 10 do
assert(ss == sock)
else
assert('timeout' == err, 'unexpected error :' .. tostring(err))
- end
+ end
err = sock:getoption("error") -- i get 'connection refused' on WinXP
if err then
print("Passed! Error is '" .. err .. "'.")
diff --git a/test/testmesg.lua b/test/testmesg.lua
index 135a008..8c086d5 100644
--- a/test/testmesg.lua
+++ b/test/testmesg.lua
@@ -34,11 +34,11 @@ r, e = smtp.send{
print(r, e)
--- creates a source to send a message with two parts. The first part is
+-- creates a source to send a message with two parts. The first part is
-- plain text, the second part is a PNG image, encoded as base64.
source = smtp.message{
headers = {
- -- Remember that headers are *ignored* by smtp.send.
+ -- Remember that headers are *ignored* by smtp.send.
from = "Sicrano ",
to = "Fulano ",
subject = "Here is a message with attachments"
@@ -49,18 +49,18 @@ source = smtp.message{
"Preamble might show up even in a MIME enabled client.",
-- first part: No headers means plain text, us-ascii.
-- The mime.eol low-level filter normalizes end-of-line markers.
- [1] = {
+ [1] = {
body = mime.eol(0, [[
- Lines in a message body should always end with CRLF.
+ Lines in a message body should always end with CRLF.
The smtp module will *NOT* perform translation. It will
perform necessary stuffing, though.
]])
},
- -- second part: Headers describe content the to be an image,
+ -- second part: Headers describe content the to be an image,
-- sent under the base64 transfer content encoding.
- -- Notice that nothing happens until the message is sent. Small
+ -- Notice that nothing happens until the message is sent. Small
-- chunks are loaded into memory and translation happens on the fly.
- [2] = {
+ [2] = {
headers = {
["ConTenT-tYpE"] = 'image/png; name="luasocket.png"',
["content-disposition"] = 'attachment; filename="luasocket.png"',
diff --git a/test/testsupport.lua b/test/testsupport.lua
index b986088..4360b6b 100644
--- a/test/testsupport.lua
+++ b/test/testsupport.lua
@@ -7,7 +7,7 @@ function readfile(name)
end
function similar(s1, s2)
- return string.lower(string.gsub(s1 or "", "%s", "")) ==
+ return string.lower(string.gsub(s1 or "", "%s", "")) ==
string.lower(string.gsub(s2 or "", "%s", ""))
end
diff --git a/test/urltest.lua b/test/urltest.lua
index ae8ba75..9a3c470 100644
--- a/test/urltest.lua
+++ b/test/urltest.lua
@@ -60,8 +60,8 @@ end
local check_absolute_url = function(base, relative, absolute)
local res = socket.url.absolute(base, relative)
- if res ~= absolute then
- io.write("absolute: In test for base='", base, "', rel='", relative, "' expected '",
+ if res ~= absolute then
+ io.write("absolute: In test for base='", base, "', rel='", relative, "' expected '",
absolute, "' but got '", res, "'\n")
os.exit()
end
@@ -73,7 +73,7 @@ local check_parse_url = function(gaba)
local parsed = socket.url.parse(url)
for i, v in pairs(gaba) do
if v ~= parsed[i] then
- io.write("parse: In test for '", url, "' expected ", i, " = '",
+ io.write("parse: In test for '", url, "' expected ", i, " = '",
v, "' but got '", tostring(parsed[i]), "'\n")
for i,v in pairs(parsed) do print(i,v) end
os.exit()
@@ -81,7 +81,7 @@ local check_parse_url = function(gaba)
end
for i, v in pairs(parsed) do
if v ~= gaba[i] then
- io.write("parse: In test for '", url, "' expected ", i, " = '",
+ io.write("parse: In test for '", url, "' expected ", i, " = '",
tostring(gaba[i]), "' but got '", v, "'\n")
for i,v in pairs(parsed) do print(i,v) end
os.exit()
@@ -92,8 +92,8 @@ end
print("testing URL parsing")
check_parse_url{
url = "scheme://user:pass$%?#wd@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "user:pass$%?#wd@host:port",
+ scheme = "scheme",
+ authority = "user:pass$%?#wd@host:port",
host = "host",
port = "port",
userinfo = "user:pass$%?#wd",
@@ -106,8 +106,8 @@ check_parse_url{
}
check_parse_url{
url = "scheme://user:pass?#wd@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "user:pass?#wd@host:port",
+ scheme = "scheme",
+ authority = "user:pass?#wd@host:port",
host = "host",
port = "port",
userinfo = "user:pass?#wd",
@@ -120,8 +120,8 @@ check_parse_url{
}
check_parse_url{
url = "scheme://user:pass-wd@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "user:pass-wd@host:port",
+ scheme = "scheme",
+ authority = "user:pass-wd@host:port",
host = "host",
port = "port",
userinfo = "user:pass-wd",
@@ -134,8 +134,8 @@ check_parse_url{
}
check_parse_url{
url = "scheme://user:pass#wd@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "user:pass#wd@host:port",
+ scheme = "scheme",
+ authority = "user:pass#wd@host:port",
host = "host",
port = "port",
userinfo = "user:pass#wd",
@@ -148,8 +148,8 @@ check_parse_url{
}
check_parse_url{
url = "scheme://user:pass#wd@host:port/path;params?query",
- scheme = "scheme",
- authority = "user:pass#wd@host:port",
+ scheme = "scheme",
+ authority = "user:pass#wd@host:port",
host = "host",
port = "port",
userinfo = "user:pass#wd",
@@ -161,8 +161,8 @@ check_parse_url{
}
check_parse_url{
url = "scheme://userinfo@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -175,8 +175,8 @@ check_parse_url{
check_parse_url{
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
- authority = "user:password@host:port",
+ scheme = "scheme",
+ authority = "user:password@host:port",
host = "host",
port = "port",
userinfo = "user:password",
@@ -190,8 +190,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/path;params?query#",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -204,8 +204,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/path;params?#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -218,8 +218,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/path;params#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -231,8 +231,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/path;?query#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -245,8 +245,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/path?query#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -258,8 +258,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port/;params?query#fragment",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -272,8 +272,8 @@ check_parse_url{
check_parse_url{
url = "scheme://userinfo@host:port",
- scheme = "scheme",
- authority = "userinfo@host:port",
+ scheme = "scheme",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -282,7 +282,7 @@ check_parse_url{
check_parse_url{
url = "//userinfo@host:port/path;params?query#fragment",
- authority = "userinfo@host:port",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -295,7 +295,7 @@ check_parse_url{
check_parse_url{
url = "//userinfo@host:port/path",
- authority = "userinfo@host:port",
+ authority = "userinfo@host:port",
host = "host",
port = "port",
userinfo = "userinfo",
@@ -305,7 +305,7 @@ check_parse_url{
check_parse_url{
url = "//userinfo@host/path",
- authority = "userinfo@host",
+ authority = "userinfo@host",
host = "host",
userinfo = "userinfo",
user = "userinfo",
@@ -314,7 +314,7 @@ check_parse_url{
check_parse_url{
url = "//user:password@host/path",
- authority = "user:password@host",
+ authority = "user:password@host",
host = "host",
userinfo = "user:password",
password = "password",
@@ -324,7 +324,7 @@ check_parse_url{
check_parse_url{
url = "//user:@host/path",
- authority = "user:@host",
+ authority = "user:@host",
host = "host",
userinfo = "user:",
password = "",
@@ -334,7 +334,7 @@ check_parse_url{
check_parse_url{
url = "//user@host:port/path",
- authority = "user@host:port",
+ authority = "user@host:port",
host = "host",
userinfo = "user",
user = "user",
@@ -344,7 +344,7 @@ check_parse_url{
check_parse_url{
url = "//host:port/path",
- authority = "host:port",
+ authority = "host:port",
port = "port",
host = "host",
path = "/path",
@@ -352,14 +352,14 @@ check_parse_url{
check_parse_url{
url = "//host/path",
- authority = "host",
+ authority = "host",
host = "host",
path = "/path",
}
check_parse_url{
url = "//host",
- authority = "host",
+ authority = "host",
host = "host",
}
@@ -433,7 +433,7 @@ check_parse_url{
check_parse_url{
url = "//userinfo@[::FFFF:129.144.52.38]:port/path;params?query#fragment",
- authority = "userinfo@[::FFFF:129.144.52.38]:port",
+ authority = "userinfo@[::FFFF:129.144.52.38]:port",
host = "::FFFF:129.144.52.38",
port = "port",
userinfo = "userinfo",
@@ -447,7 +447,7 @@ check_parse_url{
check_parse_url{
url = "scheme://user:password@[::192.9.5.5]:port/path;params?query#fragment",
scheme = "scheme",
- authority = "user:password@[::192.9.5.5]:port",
+ authority = "user:password@[::192.9.5.5]:port",
host = "::192.9.5.5",
port = "port",
userinfo = "user:password",
@@ -462,7 +462,7 @@ check_parse_url{
print("testing URL building")
check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
port = "port",
user = "user",
@@ -499,7 +499,7 @@ check_build_url{
check_build_url {
url = "scheme://user:password@host/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
user = "user",
password = "password",
@@ -511,7 +511,7 @@ check_build_url {
check_build_url {
url = "scheme://user@host/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
user = "user",
path = "/path",
@@ -522,7 +522,7 @@ check_build_url {
check_build_url {
url = "scheme://host/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
path = "/path",
params = "params",
@@ -532,7 +532,7 @@ check_build_url {
check_build_url {
url = "scheme://host/path;params#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
path = "/path",
params = "params",
@@ -541,7 +541,7 @@ check_build_url {
check_build_url {
url = "scheme://host/path#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
path = "/path",
fragment = "fragment"
@@ -549,7 +549,7 @@ check_build_url {
check_build_url {
url = "scheme://host/path",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
path = "/path",
}
@@ -567,7 +567,7 @@ check_build_url {
check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
port = "port",
user = "user",
@@ -581,7 +581,7 @@ check_build_url {
check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
port = "port",
user = "user",
@@ -596,7 +596,7 @@ check_build_url {
check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
host = "host",
port = "port",
userinfo = "user:password",
@@ -609,7 +609,7 @@ check_build_url {
check_build_url {
url = "scheme://user:password@host:port/path;params?query#fragment",
- scheme = "scheme",
+ scheme = "scheme",
authority = "user:password@host:port",
path = "/path",
params = "params",
@@ -683,7 +683,7 @@ check_absolute_url("//a/b/c/d;p?q#f", "d/e/f", "//a/b/c/d/e/f")
check_absolute_url("/a/b/c/d;p?q#f", "d/e/f", "/a/b/c/d/e/f")
check_absolute_url("a/b/c/d", "d/e/f", "a/b/c/d/e/f")
check_absolute_url("a/b/c/d/../", "d/e/f", "a/b/c/d/e/f")
-check_absolute_url("http://velox.telemar.com.br", "/dashboard/index.html",
+check_absolute_url("http://velox.telemar.com.br", "/dashboard/index.html",
"http://velox.telemar.com.br/dashboard/index.html")
check_absolute_url("http://example.com/", "../.badhost.com/", "http://example.com/.badhost.com/")
check_absolute_url("http://example.com/", "...badhost.com/", "http://example.com/...badhost.com/")
@@ -700,11 +700,11 @@ check_absolute_url("http://example.com/a/b/c/d/", "../x/a/../y/z/../../../../q",
print("testing path parsing and composition")
check_parse_path("/eu/tu/ele", { "eu", "tu", "ele"; is_absolute = 1 })
check_parse_path("/eu/", { "eu"; is_absolute = 1, is_directory = 1 })
-check_parse_path("eu/tu/ele/nos/vos/eles/",
+check_parse_path("eu/tu/ele/nos/vos/eles/",
{ "eu", "tu", "ele", "nos", "vos", "eles"; is_directory = 1})
check_parse_path("/", { is_absolute = 1, is_directory = 1})
check_parse_path("", { })
-check_parse_path("eu%01/%02tu/e%03l%04e/nos/vos%05/e%12les/",
+check_parse_path("eu%01/%02tu/e%03l%04e/nos/vos%05/e%12les/",
{ "eu\1", "\2tu", "e\3l\4e", "nos", "vos\5", "e\18les"; is_directory = 1})
check_parse_path("eu/tu", { "eu", "tu" })
diff --git a/test/utestclnt.lua b/test/utestclnt.lua
index 34a0718..7f10643 100644
--- a/test/utestclnt.lua
+++ b/test/utestclnt.lua
@@ -54,30 +54,30 @@ function check_timeout(tm, sl, elapsed, err, opp, mode, alldone)
if not err then warn("must be buffered")
elseif err == "timeout" then pass("proper timeout")
else fail("unexpected error '%s'", err) end
- else
- if err ~= "timeout" then fail("should have timed out")
+ else
+ if err ~= "timeout" then fail("should have timed out")
else pass("proper timeout") end
end
else
if mode == "total" then
- if elapsed > tm then
+ if elapsed > tm then
if err ~= "timeout" then fail("should have timed out")
else pass("proper timeout") end
elseif elapsed < tm then
- if err then fail(err)
+ if err then fail(err)
else pass("ok") end
- else
- if alldone then
- if err then fail("unexpected error '%s'", err)
+ else
+ if alldone then
+ if err then fail("unexpected error '%s'", err)
else pass("ok") end
else
- if err ~= "timeout" then fail(err)
+ if err ~= "timeout" then fail(err)
else pass("proper timeoutk") end
end
end
- else
- if err then fail(err)
- else pass("ok") end
+ else
+ if err then fail(err)
+ else pass("ok") end
end
end
end
@@ -104,7 +104,7 @@ function reconnect()
print("done " .. i)
]]
data, err = uconnect(host, port)
- if not data then fail(err)
+ if not data then fail(err)
else pass("connected!") end
end
@@ -116,8 +116,8 @@ else pass("connected!") end
------------------------------------------------------------------------
function test_methods(sock, methods)
for _, v in pairs(methods) do
- if type(sock[v]) ~= "function" then
- fail(sock.class .. " method '" .. v .. "' not registered")
+ if type(sock[v]) ~= "function" then
+ fail(sock.class .. " method '" .. v .. "' not registered")
end
end
pass(sock.class .. " methods are ok")
@@ -132,7 +132,7 @@ function test_mixed(len)
local p3 = "raw " .. string.rep("z", inter) .. "bytes"
local p4 = "end" .. string.rep("w", inter) .. "bytes"
local bp1, bp2, bp3, bp4
-remote (string.format("str = data:receive(%d)",
+remote (string.format("str = data:receive(%d)",
string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4)))
sent, err = data:send(p1..p2..p3..p4)
if err then fail(err) end
@@ -172,7 +172,7 @@ function test_rawline(len)
reconnect()
local str, str10, back, err
str = string.rep(string.char(47), math.mod(len, 10))
- str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
+ str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
math.floor(len/10))
str = str .. str10
remote "str = data:receive()"
@@ -221,7 +221,7 @@ function test_totaltimeoutreceive(len, tm, sl)
data:settimeout(tm, "total")
local t = socket.gettime()
str, err, partial, elapsed = data:receive(2*len)
- check_timeout(tm, sl, elapsed, err, "receive", "total",
+ check_timeout(tm, sl, elapsed, err, "receive", "total",
string.len(str or partial) == 2*len)
end
@@ -241,7 +241,7 @@ function test_totaltimeoutsend(len, tm, sl)
data:settimeout(tm, "total")
str = string.rep("a", 2*len)
total, err, partial, elapsed = data:send(str)
- check_timeout(tm, sl, elapsed, err, "send", "total",
+ check_timeout(tm, sl, elapsed, err, "send", "total",
total == 2*len)
end
@@ -261,7 +261,7 @@ function test_blockingtimeoutreceive(len, tm, sl)
]], 2*tm, len, sl, sl))
data:settimeout(tm)
str, err, partial, elapsed = data:receive(2*len)
- check_timeout(tm, sl, elapsed, err, "receive", "blocking",
+ check_timeout(tm, sl, elapsed, err, "receive", "blocking",
string.len(str or partial) == 2*len)
end
@@ -294,10 +294,10 @@ function empty_connect()
data = server:accept()
]]
data, err = socket.connect("", port)
- if not data then
+ if not data then
pass("ok")
data = socket.connect(host, port)
- else
+ else
pass("gethostbyname returns localhost on empty string...")
end
end
@@ -331,7 +331,7 @@ function test_closed()
data:close()
data = nil
]], str))
- -- try to get a line
+ -- try to get a line
back, err, partial = data:receive()
if not err then fail("should have gotten 'closed'.")
elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
@@ -344,25 +344,25 @@ function test_closed()
data = nil
]]
total, err, partial = data:send(string.rep("ugauga", 100000))
- if not err then
+ if not err then
pass("failed: output buffer is at least %d bytes long!", total)
- elseif err ~= "closed" then
+ elseif err ~= "closed" then
fail("got '"..err.."' instead of 'closed'.")
- else
- pass("graceful 'closed' received after %d bytes were sent", partial)
+ else
+ pass("graceful 'closed' received after %d bytes were sent", partial)
end
end
------------------------------------------------------------------------
function test_selectbugs()
local r, s, e = socket.select(nil, nil, 0.1)
- assert(type(r) == "table" and type(s) == "table" and
+ assert(type(r) == "table" and type(s) == "table" and
(e == "timeout" or e == "error"))
pass("both nil: ok")
local udp = socket.udp()
udp:close()
r, s, e = socket.select({ udp }, { udp }, 0.1)
- assert(type(r) == "table" and type(s) == "table" and
+ assert(type(r) == "table" and type(s) == "table" and
(e == "timeout" or e == "error"))
pass("closed sockets: ok")
e = pcall(socket.select, "wrong", 1, 0.1)
@@ -380,7 +380,7 @@ function accept_timeout()
local t = socket.gettime()
s:settimeout(1)
local c, e = s:accept()
- assert(not c, "should not accept")
+ assert(not c, "should not accept")
assert(e == "timeout", string.format("wrong error message (%s)", e))
t = socket.gettime() - t
assert(t < 2, string.format("took to long to give up (%gs)", t))
@@ -398,9 +398,9 @@ function connect_timeout()
local t = socket.gettime()
local r, e = c:connect("127.0.0.2", 80)
assert(not r, "should not connect")
- assert(socket.gettime() - t < 2, "took too long to give up.")
+ assert(socket.gettime() - t < 2, "took too long to give up.")
c:close()
- print("ok")
+ print("ok")
end
------------------------------------------------------------------------
@@ -463,9 +463,9 @@ function getstats_test()
data:receive(c)
t = t + c
local r, s, a = data:getstats()
- assert(r == t, "received count failed" .. tostring(r)
+ assert(r == t, "received count failed" .. tostring(r)
.. "/" .. tostring(t))
- assert(s == t, "sent count failed" .. tostring(s)
+ assert(s == t, "sent count failed" .. tostring(s)
.. "/" .. tostring(t))
end
print("ok")
@@ -473,7 +473,7 @@ end
------------------------------------------------------------------------
-function test_nonblocking(size)
+function test_nonblocking(size)
reconnect()
print("Testing " .. 2*size .. " bytes")
remote(string.format([[
diff --git a/test/utestsrvr.lua b/test/utestsrvr.lua
index a96b570..b6e4246 100644
--- a/test/utestsrvr.lua
+++ b/test/utestsrvr.lua
@@ -9,7 +9,7 @@ ack = "\n";
while 1 do
print("server: waiting for client connection...");
control = assert(server:accept());
- while 1 do
+ while 1 do
command = assert(control:receive());
assert(control:send(ack));
((loadstring or load)(command))();
--
cgit v1.2.3-55-g6feb
From 2a76cb906cb955a83ed76b8e47cc76c77ce8e15f Mon Sep 17 00:00:00 2001
From: Julian Squires
Date: Fri, 16 Oct 2020 12:18:46 -0230
Subject: http.lua: set transfer-encoding if source and no content-length
If a source is specified without a content-length header, LuaSocket
sends the data in the chunked transfer coding; however, it doesn't set
the transfer-encoding header. While I recognize that the user can set
this manually, this is a gotcha that has caught me multiple times.
RFC7230, section 3.3.3
(https://tools.ietf.org/html/rfc7230#section-3.3.3)
is clear about this; if neither content-length nor transfer-encoding
chunked are specified, the request message body length is zero. While
some servers may ignore this, I have encountered several that follow
the RFC in this regard, most recently golang's net/http.
---
src/http.lua | 7 +++++++
1 file changed, 7 insertions(+)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index e3a1742..1330355 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -283,6 +283,13 @@ local function adjustrequest(reqt)
nreqt.uri = reqt.uri or adjusturi(nreqt)
-- adjust headers in request
nreqt.headers = adjustheaders(nreqt)
+ if nreqt.source
+ and not nreqt.headers["content-length"]
+ and not nreqt.headers["transfer-encoding"]
+ then
+ nreqt.headers["transfer-encoding"] = "chunked"
+ end
+
-- ajust host and port if there is a proxy
nreqt.host, nreqt.port = adjustproxy(nreqt)
return nreqt
--
cgit v1.2.3-55-g6feb
From 8c2ff7217e2a205eb107a6f48b04ff1b2b3090a1 Mon Sep 17 00:00:00 2001
From: Henri D
Date: Sat, 8 Oct 2022 08:42:36 +0200
Subject: fix(http): Allow relative redirect on https (#395)
Location header can now be relative: https://httpwg.org/specs/rfc9110.html#field.location
---
src/http.lua | 5 +++--
test/httptest.lua | 31 +++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 2 deletions(-)
(limited to 'src/http.lua')
diff --git a/src/http.lua b/src/http.lua
index 1330355..fbd5ff6 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -300,6 +300,8 @@ local function shouldredirect(reqt, code, headers)
if not location then return false end
location = string.gsub(location, "%s", "")
if location == "" then return false end
+ -- the RFC says the redirect URL may be relative
+ location = url.absolute(reqt.url, location)
local scheme = url.parse(location).scheme
if scheme and (not SCHEMES[scheme]) then return false end
-- avoid https downgrades
@@ -323,8 +325,7 @@ end
local trequest, tredirect
--[[local]] function tredirect(reqt, location)
- -- the RFC says the redirect URL has to be absolute, but some
- -- servers do not respect that
+ -- the RFC says the redirect URL may be relative
local newurl = url.absolute(reqt.url, location)
-- if switching schemes, reset port and create function
if url.parse(newurl).scheme ~= reqt.scheme then
diff --git a/test/httptest.lua b/test/httptest.lua
index 63ff921..3457b07 100644
--- a/test/httptest.lua
+++ b/test/httptest.lua
@@ -265,6 +265,37 @@ ignore = {
}
check_request(request, expect, ignore)
+-- Use https://httpbin.org/#/Dynamic_data/get_base64__value_ for testing
+-----------------------------------------------------
+io.write("testing absolute https redirection: ")
+request = {
+ url = "https://httpbin.org/redirect-to?url=https://httpbin.org/base64/THVhIFNvY2tldA=="
+}
+expect = {
+ code = 200,
+ body = "Lua Socket"
+}
+ignore = {
+ status = 1,
+ headers = 1
+}
+check_request(request, expect, ignore)
+
+-----------------------------------------------------
+io.write("testing relative https redirection: ")
+request = {
+ url = "https://httpbin.org/redirect-to?url=/base64/THVhIFNvY2tldA=="
+}
+expect = {
+ code = 200,
+ body = "Lua Socket"
+}
+ignore = {
+ status = 1,
+ headers = 1
+}
+check_request(request, expect, ignore)
+
------------------------------------------------------------------------
--[[
io.write("testing proxy with redirection: ")
--
cgit v1.2.3-55-g6feb