104 lines
3.4 KiB
Lua
104 lines
3.4 KiB
Lua
-- test scheme validation and normalization in copas/http.lua
|
|
--
|
|
-- Covers the fix that:
|
|
-- * rejects non-string/unsupported request schemes before a connection
|
|
-- is attempted (instead of silently falling back to plain HTTP), and
|
|
-- * normalizes the scheme to lowercase (from the url and from an
|
|
-- explicit override) so mixed-case "HTTPS" URLs select the TLS
|
|
-- transport instead of being silently treated as plain HTTP.
|
|
|
|
local copas = require("copas")
|
|
local http = copas.http
|
|
local ltn12 = require("ltn12")
|
|
|
|
local failures = 0
|
|
|
|
local function check(cond, msg)
|
|
if cond then
|
|
print("OK: "..msg)
|
|
else
|
|
print("FAILED: "..msg)
|
|
failures = failures + 1
|
|
end
|
|
end
|
|
|
|
-- helper: build a request table with a stub `create` so no real connection
|
|
-- is ever attempted; the stub records the (normalized) request table it
|
|
-- receives and aborts the request before any socket is opened.
|
|
local function stubrequest(url, overrides)
|
|
local captured
|
|
local reqt = {
|
|
url = url,
|
|
target = {},
|
|
create = function(nreqt)
|
|
captured = nreqt
|
|
return nil, "test-abort-before-connect"
|
|
end,
|
|
}
|
|
for k, v in pairs(overrides or {}) do
|
|
reqt[k] = v
|
|
end
|
|
reqt.sink = ltn12.sink.table(reqt.target)
|
|
local ok, err = http.request(reqt)
|
|
return ok, err, captured
|
|
end
|
|
|
|
copas.addthread(function()
|
|
|
|
-- non-string scheme (explicit override) is rejected before connecting
|
|
do
|
|
local ok, err, captured = stubrequest("http://localhost/", { scheme = 123 })
|
|
check(ok == nil and tostring(err):match("invalid scheme") ~= nil,
|
|
"non-string scheme is rejected, got: "..tostring(err))
|
|
check(captured == nil, "no connection is attempted for an invalid scheme")
|
|
end
|
|
|
|
-- unsupported (but well-formed) scheme is rejected before connecting
|
|
do
|
|
local ok, err, captured = stubrequest("ftp://localhost/")
|
|
check(ok == nil and tostring(err):match("unsupported scheme") ~= nil,
|
|
"unsupported scheme is rejected, got: "..tostring(err))
|
|
check(captured == nil, "no connection is attempted for an unsupported scheme")
|
|
end
|
|
|
|
-- mixed-case scheme from the url is normalized to lowercase
|
|
do
|
|
local _, _, captured = stubrequest("HTTPS://localhost/")
|
|
check(captured and captured.scheme == "https",
|
|
"mixed-case 'HTTPS' url scheme is normalized to lowercase, got: "..
|
|
tostring(captured and captured.scheme))
|
|
end
|
|
|
|
-- mixed-case scheme passed as an explicit override is normalized too
|
|
do
|
|
local _, _, captured = stubrequest("http://localhost/", { scheme = "HtTp" })
|
|
check(captured and captured.scheme == "http",
|
|
"mixed-case explicit scheme override is normalized to lowercase, got: "..
|
|
tostring(captured and captured.scheme))
|
|
end
|
|
|
|
-- once normalized, a "https" scheme must select the TLS transport,
|
|
-- not silently fall back to plain HTTP
|
|
do
|
|
local create = http.getcreatefunc()
|
|
local conn = create({ url = "https://localhost/", scheme = "https" })
|
|
check(conn.ssl_params.wrap ~= false, "normalized 'https' scheme selects the TLS transport")
|
|
end
|
|
|
|
-- a plain "http" scheme must not select the TLS transport
|
|
do
|
|
local create = http.getcreatefunc()
|
|
local conn = create({ url = "http://localhost/", scheme = "http" })
|
|
check(conn.ssl_params.wrap == false, "'http' scheme does not select the TLS transport")
|
|
end
|
|
|
|
if failures > 0 then
|
|
print(failures.." check(s) failed")
|
|
os.exit(1)
|
|
end
|
|
|
|
print("all checks passed")
|
|
os.exit(0)
|
|
end)
|
|
|
|
copas.loop()
|