-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
roles: introduce role for http servers
This patch adds `roles.httpd`. This role allows to configure one or more HTTP servers. Those servers could be reused by several other roles. Servers could be accessed by their names (from the config). `get_server(name)` method returns a server by its name. If `nil` is passed, default server is returned. The server is default, if it has `DEFAULT_SERVER_NAME` (`"default"`) as a name. Closes #196
- Loading branch information
Showing
13 changed files
with
588 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Install | ||
install(FILES httpd.lua DESTINATION ${TARANTOOL_INSTALL_LUADIR}/roles) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
local checks = require('checks') | ||
local urilib = require('uri') | ||
local http_server = require('http.server') | ||
|
||
local M = { | ||
DEFAULT_SERVER_NAME = 'default', | ||
} | ||
local servers = {} | ||
|
||
local function parse_listen(listen) | ||
if listen == nil then | ||
return nil, nil, "must exist" | ||
end | ||
if type(listen) ~= "string" and type(listen) ~= "number" then | ||
return nil, nil, "must be a string or a number, got " .. type(listen) | ||
end | ||
|
||
local host | ||
local port | ||
if type(listen) == "string" then | ||
local uri, err = urilib.parse(listen) | ||
if err ~= nil then | ||
return nil, nil, "failed to parse URI: " .. err | ||
end | ||
|
||
if uri.scheme ~= nil then | ||
if uri.scheme == "unix" then | ||
uri.unix = uri.path | ||
else | ||
return nil, nil, "URI scheme is not supported" | ||
end | ||
end | ||
|
||
if uri.login ~= nil or uri.password then | ||
return nil, nil, "URI login and password are not supported" | ||
end | ||
|
||
if uri.query ~= nil then | ||
return nil, nil, "URI query component is not supported" | ||
end | ||
|
||
if uri.unix ~= nil then | ||
host = "unix/" | ||
port = uri.unix | ||
else | ||
if uri.service == nil then | ||
return nil, nil, "URI must contain a port" | ||
end | ||
|
||
port = tonumber(uri.service) | ||
if port == nil then | ||
return nil, nil, "URI port must be a number" | ||
end | ||
if uri.host ~= nil then | ||
host = uri.host | ||
elseif uri.ipv4 ~= nil then | ||
host = uri.ipv4 | ||
elseif uri.ipv6 ~= nil then | ||
host = uri.ipv6 | ||
else | ||
host = "0.0.0.0" | ||
end | ||
end | ||
elseif type(listen) == "number" then | ||
host = "0.0.0.0" | ||
port = listen | ||
end | ||
|
||
if type(port) == "number" and (port < 1 or port > 65535) then | ||
return nil, nil, "port must be in the range [1, 65535]" | ||
end | ||
return host, port, nil | ||
end | ||
|
||
local function apply_http(name, node) | ||
local host, port, err = parse_listen(node.listen) | ||
if err ~= nil then | ||
error("failed to parse URI: " .. err) | ||
end | ||
|
||
if servers[name] == nil then | ||
local httpd = http_server.new(host, port) | ||
httpd:start() | ||
servers[name] = { | ||
httpd = httpd, | ||
routes = {}, | ||
} | ||
end | ||
end | ||
|
||
M.validate = function(conf) | ||
if conf ~= nil and type(conf) ~= "table" then | ||
error("configuration must be a table, got " .. type(conf)) | ||
end | ||
conf = conf or {} | ||
|
||
for name, node in pairs(conf) do | ||
if type(name) ~= 'string' then | ||
error("name of the server must be a string") | ||
end | ||
|
||
local _, _, err = parse_listen(node.listen) | ||
if err ~= nil then | ||
error("failed to parse http 'listen' param: " .. err) | ||
end | ||
end | ||
end | ||
|
||
M.apply = function(conf) | ||
-- This should be called on the role's lifecycle, but it's better to give | ||
-- a meaningful error if something goes wrong. | ||
M.validate(conf) | ||
|
||
for name, node in pairs(conf or {}) do | ||
apply_http(name, node) | ||
end | ||
end | ||
|
||
M.stop = function() | ||
for _, server in pairs(servers) do | ||
server.httpd:stop() | ||
end | ||
servers = {} | ||
end | ||
|
||
M.get_server = function(name) | ||
checks('?string') | ||
|
||
name = name or M.DEFAULT_SERVER_NAME | ||
return (servers[name] or {}).httpd | ||
end | ||
|
||
return M |
Oops, something went wrong.