Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ Creates a new connection to an HTTP server.
- `port` (string|integer): port to connect to in numeric form
e.g. `"80"` or `80`

- `path` (string): path to connect to (UNIX sockets)

- `sendname` (string|boolean, optional): the [TLS SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) host to send.
defaults to `true`
- `true` indicates to copy the `host` field
Expand Down
1 change: 1 addition & 0 deletions http/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ local function connect(options, timeout)
family = options.family;
host = options.host;
port = options.port;
path = options.path;
sendname = options.sendname;
v6only = options.v6only;
nodelay = true;
Expand Down
16 changes: 12 additions & 4 deletions http/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ local server_mt = {
--[[ Starts listening on the given socket

Takes a table of options:
- `.host`: address to bind to (required)
- `.host`: address to bind to (required if not `.path`)
- `.port`: port to bind to (optional if tls isn't `nil`, in which case defaults to 80 for `.tls == false` or 443 if `.tls == true`)
- `.path`: path to UNIX socket (required if not `.host`)
- `.v6only`: allow ipv6 only (no ipv4-mapped-ipv6)
- `.reuseaddr`: turn on SO_REUSEADDR flag?
- `.reuseport`: turn on SO_REUSEPORT flag?
Expand All @@ -177,9 +178,11 @@ Takes a table of options:
]]
local function listen(tbl)
local tls = tbl.tls
local host = assert(tbl.host, "need host")
local host = tbl.host
local path = tbl.path
assert(host or path, "need host or path")
local port = tbl.port
if port == nil then
if host and port == nil then
if tls == true then
port = "443"
elseif tls == false then
Expand All @@ -190,11 +193,16 @@ local function listen(tbl)
end
local ctx = tbl.ctx
if ctx == nil and tls ~= false then
ctx = new_ctx(host)
if host then
ctx = new_ctx(host)
else
error("Custom OpenSSL context required when using a UNIX domain socket")
end
end
local s = assert(cs.listen{
host = host;
port = port;
path = path;
v6only = tbl.v6only;
reuseaddr = tbl.reuseaddr;
reuseport = tbl.reuseport;
Expand Down
89 changes: 73 additions & 16 deletions spec/server_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@ describe("http.server module", function()
local new_headers = require "http.headers".new
local cqueues = require "cqueues"
local cs = require "cqueues.socket"
local function simple_test(tls, version)
local function assert_loop(cq, timeout)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might need to rebase again, as assert_loop was factored out.

local ok, err, _, thd = cq:loop(timeout)
if not ok then
if thd then
err = debug.traceback(thd, err)
end
error(err, 2)
end
end
local function simple_test(tls, version, path)
local cq = cqueues.new()
local s = server.listen {
host = "localhost";
port = 0;
}
local options = {}
if path then
options.path = path
else
options.host = "localhost"
options.port = 0
end
options.version = version
options.tls = tls
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options doesn't need/want TLS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed tonight that it does; instead it assumes (at least on my system) that it needs to generate a certificate (which breaks atm because certificates are pending).

local s = server.listen(options)
assert(s:listen())
local _, host, port = s:localname()
local host, port
if not path then
local _
_, host, port = s:localname()
end
local on_stream = spy.new(function(stream)
stream:get_headers()
stream:shutdown()
Expand All @@ -22,12 +41,16 @@ describe("http.server module", function()
s:close()
end)
cq:wrap(function()
local conn = client.connect {
host = host;
port = port;
tls = tls;
version = version;
}
local client_options = {}
if path then
client_options.path = path
else
client_options.host = host
client_options.port = port
end
client_options.tls = tls
client_options.version = version
local conn = client.connect(client_options)
local stream = conn:new_stream()
local headers = new_headers()
headers:append(":method", "GET")
Expand All @@ -41,16 +64,16 @@ describe("http.server module", function()
assert.truthy(cq:empty())
assert.spy(on_stream).was.called()
end
it("works with plain http 1.1", function()
it("works with plain http 1.1 using IP", function()
simple_test(false, 1.1)
end)
it("works with https 1.1", function()
it("works with https 1.1 using IP", function()
simple_test(true, 1.1)
end)
it("works with plain http 2.0", function()
it("works with plain http 2.0 using IP", function()
simple_test(false, 2.0)
end);
(require "http.tls".has_alpn and it or pending)("works with https 2.0", function()
(require "http.tls".has_alpn and it or pending)("works with https 2.0 using IP", function()
simple_test(true, 2.0)
end)
it("taking socket from underlying connection is handled well by server", function()
Expand Down Expand Up @@ -84,4 +107,38 @@ describe("http.server module", function()
assert.truthy(cq:empty())
assert.spy(on_stream).was.called()
end)
--[[
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this comment down to above the pending test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to my todo list, as well as the below comment

--
-- Until there is a way to generate OpenSSL contexts in this file for
-- UNIX domain sockets, there is no way to use TLS with this. Because
-- of this, the status for using TLS with UNIX domain sockets is
-- pending.
--
--]]
local socket_path = os.tmpname()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not generate one per test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to? If you remove it in the finally() call, it should be done after the it() call, right?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's fine I guess.

os.remove(socket_path) -- in case it was generated automatically
it("works with plain http 1.1 using UNIX socket domain", function()
simple_test(false, 1.1, socket_path)
finally(function()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to call finally before the test throws.

os.remove(socket_path)
end)
end)
pending("works with https 1.1 using UNIX socket domain", function()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this pending?

oh, just saw the comment down on line 99. please move it up?

simple_test(true, 1.1, socket_path)
finally(function()
os.remove(socket_path)
end)
end)
it("works with plain http 2.0 using UNIX socket domain", function()
simple_test(false, 2.0, socket_path)
finally(function()
os.remove(socket_path)
end)
end);
pending("works with https 2.0 using UNIX socket domain", function()
simple_test(true, 2.0, socket_path)
finally(function()
os.remove(socket_path)
end)
end)
end)