Skip to content
Closed
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- Network error shows with fixed splash panel instead of notification.

- Built-in HTTP server upgraded to `v2`. Backward compatibility with
`v1` is preserved by introducing intermediate layer, which substitutes
`cartridge.service_get('httpd')`. One can access true `v2` server via
`cartridge.service_get('httpd-2')`.

### Fixed

- DDL failure if spaces is `null` in input schema.
Expand Down
2 changes: 1 addition & 1 deletion cartridge-scm-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ source = {
dependencies = {
'lua >= 5.1',
'ddl == 1.0.0-1',
'http == 1.0.5-1',
'http == 2.1.0-1',
'checks == 3.0.1-1',
'lulpeg == 0.1.2-1',
'errors == 2.1.2-1',
Expand Down
9 changes: 7 additions & 2 deletions cartridge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ local checks = require('checks')
local errors = require('errors')
local membership = require('membership')
local membership_network = require('membership.network')
local http = require('http.server')
local http_server = require('http.server')
local http_router = require('http.router')

local http_adapter = require('cartridge.http-adapter')
local rpc = require('cartridge.rpc')
local auth = require('cartridge.auth')
local utils = require('cartridge.utils')
Expand Down Expand Up @@ -449,10 +451,12 @@ local function cfg(opts, box_opts)
opts.http_enabled = true
end
if opts.http_enabled then
local httpd = http.new(
local httpd2 = http_server.new(
'0.0.0.0', opts.http_port,
{ log_requests = false }
)
httpd2:set_router(http_router.new())
local httpd = http_adapter.new(httpd2)

local ok, err = HttpInitError:pcall(httpd.start, httpd)
if not ok then
Expand All @@ -471,6 +475,7 @@ local function cfg(opts, box_opts)

local srv_name = httpd.tcp_server:name()
log.info('Listening HTTP on %s:%s', srv_name.host, srv_name.port)
service_registry.set('httpd-2', httpd2)
service_registry.set('httpd', httpd)
end

Expand Down
230 changes: 230 additions & 0 deletions cartridge/http-adapter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
-- The layer which provides http-v1 api to interact with http-v2

local lib = require('http.lib')
local utils = require('http.utils')

local function cached_query_param(self, name)
if name == nil then
return self.query_params
end
return self.query_params[ name ]
end

local function request_line(self)
local rstr = self.path

local query_string = self.query
if query_string ~= nil and query_string ~= '' then
rstr = rstr .. '?' .. query_string
end

return utils.sprintf("%s %s %s",
self['REQUEST_METHOD'],
rstr,
self['SERVER_PROTOCOL'] or 'HTTP/?')
end

local function query_param(self, name)
if self.query ~= nil and string.len(self.query) == 0 then
rawset(self, 'query_params', {})
else
local params = lib.params(self['QUERY_STRING'])
local pres = {}
for k, v in pairs(params) do
pres[ utils.uri_unescape(k) ] = utils.uri_unescape(v)
end
rawset(self, 'query_params', pres)
end

rawset(self, 'query_param', cached_query_param)
return self:query_param(name)
end

local function cookie(self, cookiename)
if self.headers.cookie == nil then
return nil
end
for k, v in string.gmatch(
self.headers.cookie, "([^=,; \t]+)=([^,; \t]+)") do
if k == cookiename then
return utils.uri_unescape(v)
end
end
return nil
end

local function create_http_v1_request(request)
local new_request = table.copy(request)

local new_request_mt = table.deepcopy(getmetatable(request))
local mt_index_table = new_request_mt.__index

new_request.headers = request:headers()
new_request.path = request:path()
new_request.peer = request:peer()
new_request.method = request:method()
new_request.proto = request:proto()
new_request.query = request:query()

-- redefine methods, which have conflicts with http-v1
mt_index_table.request_line = request_line
mt_index_table.query_param = query_param
mt_index_table.cookie = cookie

setmetatable(new_request, new_request_mt)
return new_request
end

local function server_httpd_start(self)
self.server:start()
return self
end

local function server_httpd_stop(self)
self.server:stop()
return self
end

local function server_route(self, opts, handler)
local decorated_handler = handler
if type(handler) == 'function'then
decorated_handler = function(req)
local hooks = self.hooks
if hooks.before_dispatch ~= nil then
hooks.before_dispatch(self, req)
end

local resp = handler(create_http_v1_request(req))

if hooks.after_dispatch ~= nil then
hooks.after_dispatch(req, resp)
end

return resp
end
end
self.router:route(opts, decorated_handler)
return self
end

local function server_match(self, method, route)
return self.router:match(method, route)
end

local function server_helper(self, name, handler)
self.router:helper(name, handler)
return self
end

local function server_hook(self, name, handler)
self.router:hook(name, handler)
return self
end

local function server_url_for(self, name, args, query)
return self.router:url_for(name, args, query)
end

local server_options_set = {
router = true,
log_requests = true,
log_errors = true,
display_errors = true,
}

local router_options_set = {
max_header_size = true,
header_timeout = true,
app_dir = true,
charset = true,
cache_templates = true,
cache_controllers = true,
cache_static = true,
}

local server_fields_set = {
host = true,
port = true,
tcp_server = true,
is_run = true,
}

local router_fields_set = {
routes = true,
iroutes = true,
helpers = true,
hooks = true,
cache = true,
}

local function new_adapter(server)
local router = server:router()
local adapter_options, adapter_options_body = {}, {}
local adapter_options_mt = {
__newindex = function(_, key, value)
if server_options_set[key] then
server.options[key] = value
elseif router_options_set[key] then
router.options[key] = value
else
adapter_options_body[key] = value
end
end,
__index = function(_, key)
if server_options_set[key] then
return server.options[key]
elseif router_options_set[key] then
return router.options[key]
else
return adapter_options_body[key]
end
end
}
setmetatable(adapter_options, adapter_options_mt)
local adapter_body = {}
local adapter_mt = {
__newindex = function(_, key, value)
if server_fields_set[key] then
server[key] = value
elseif router_fields_set[key] then
router[key] = value
else
adapter_body[key] = value
end
end,
__index = function(_, key)
if server_fields_set[key] then
return server[key]
elseif router_fields_set[key] then
return router[key]
else
return adapter_body[key]
end
end
}

local server_adapter = {
-- http2
server = server,
router = router,

-- http1
start = server_httpd_start,
stop = server_httpd_stop,

options = adapter_options,

-- methods
route = server_route,
match = server_match,
helper = server_helper,
hook = server_hook,
url_for = server_url_for,
}

return setmetatable(server_adapter, adapter_mt)
end

return {
new = new_adapter,
}
11 changes: 7 additions & 4 deletions test/integration/feedback_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ local g = t.group()

local log = require('log')
local json = require('json')
local http = require('http.server')
local http_server = require('http.server')
local http_router = require('http.router')
local fiber = require('fiber')
local test_helper = require('test.helper')
local helpers = require('cartridge.test-helpers')
Expand All @@ -17,14 +18,16 @@ end
g.before_all = function()
g.tempdir = fio.tempdir()

g.httpd = http.new('127.0.0.1', nil, {log_requests = false})
g.httpd:start()
g.httpd = http_server.new('127.0.0.1', nil, {log_requests = false})
local router = http_router.new({})
g.httpd:set_router(router)

g.httpd:route({
router:route({
path = '/',
method = 'POST'
}, handle_feedback)

g.httpd:start()

local feedback_host = string.format('http://127.0.0.1:%d',
g.httpd.tcp_server:name().port
Expand Down
3 changes: 3 additions & 0 deletions test/unit/http-1.1.0/controllers/module/controller.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
return {
action = function(self) return self:render() end
}
9 changes: 9 additions & 0 deletions test/unit/http-1.1.0/public/hello.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<title>Hello, tarantool</title>
</head>
<body>
static html file
</body>
</html>

5 changes: 5 additions & 0 deletions test/unit/http-1.1.0/public/lorem.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ut nisl pulvinar, ornare justo nec, vulputate enim. Phasellus porta erat quis tortor volutpat, sed semper dui imperdiet. Nullam efficitur ornare urna, volutpat dignissim augue efficitur ac. Nunc dignissim consectetur sapien vel dignissim. Aliquam a lorem urna. Phasellus mollis faucibus dictum. Phasellus tristique lacus et dui sollicitudin, in hendrerit risus tincidunt. Aliquam massa leo, semper et enim at, iaculis gravida orci. Praesent eu odio quis nisi malesuada congue.
Nam in ipsum magna. Ut convallis arcu eget eleifend egestas. Mauris commodo ac metus quis vehicula. Proin mi nisl, bibendum sed justo vel, dictum auctor libero. In aliquet ex sit amet enim varius, in eleifend arcu dapibus. Quisque pellentesque mauris a ipsum iaculis, sit amet porta felis fermentum. Nunc mattis nibh et placerat fringilla. Nullam porta, lorem at facilisis scelerisque, felis dolor commodo turpis, ultrices dapibus ipsum dui vitae tortor. Donec a interdum erat.
Sed elementum enim vel egestas auctor. Proin hendrerit erat a erat viverra, id accumsan ligula porttitor. Maecenas rutrum eget risus eget fringilla. Aenean at mauris posuere, lacinia massa at, laoreet urna. Sed varius tortor ut massa tristique, id lobortis risus venenatis. Praesent vel felis sit amet orci interdum lacinia. Mauris id cursus lectus. Cras consequat facilisis justo in hendrerit. Morbi faucibus convallis tellus, non pulvinar felis mattis vitae. Aliquam fringilla a nisi et hendrerit. Sed tincidunt mauris massa, non consectetur erat tempus ut. Suspendisse a libero nulla.
Nunc magna enim, efficitur vel urna et, volutpat pretium neque. Aliquam nec mauris nec eros eleifend vestibulum at et purus. Mauris blandit sem massa, id placerat neque volutpat sit amet. Nullam gravida sollicitudin enim quis fringilla. Donec ante justo, placerat nec tortor ut, ullamcorper dignissim ligula. Morbi ac arcu odio. Pellentesque laoreet mollis urna, sit amet ultrices nisl dapibus laoreet. Nunc facilisis et urna at ullamcorper.
Proin sed mollis orci. In pulvinar velit varius lorem pretium sagittis. Morbi non erat est. Nullam at quam magna. In ac vehicula nulla. Praesent vel euismod turpis. Integer erat enim, accumsan nec eleifend nec, congue sit amet magna. Phasellus non massa id lectus dictum convallis ultricies ac augue. Ut nec ante quis justo placerat efficitur.
9 changes: 9 additions & 0 deletions test/unit/http-1.1.0/templates/helper.html.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<title><%= helper_title('world') %></title>
</head>
<body>
Helpers test
</body>
</html>

10 changes: 10 additions & 0 deletions test/unit/http-1.1.0/templates/module/controller/action.html.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<html>
<head>
<title>Hello, Tarantool httpd!</title>
</head>
<body>
action: <%= action %>
controller: <%= controller %>
</body>
</html>

3 changes: 3 additions & 0 deletions test/unit/http-1.1.0/templates/module/controller/action.js.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"hello":"json template <%= format %>"
}
9 changes: 9 additions & 0 deletions test/unit/http-1.1.0/templates/test.html.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<title><%= title %></title>
</head>
<body>
Tarantool is an application server
</body>
</html>

Loading