diff --git a/src/engine/core/html5/engine.js b/src/engine/core/html5/engine.js
index 50af3ce..2fb61e9 100644
--- a/src/engine/core/html5/engine.js
+++ b/src/engine/core/html5/engine.js
@@ -66,8 +66,17 @@ document.addEventListener('DOMContentLoaded', async () => {
}
const browser_protocol_http = {
handler: (self) => {
- self.promise()
- fetch(self.url)
+ const method = self.method
+ const headers = new Headers(self.headers_dict)
+ const params = new URLSearchParams(self.params_dict)
+ const url = `${self.url}` + '?' + params.toString()
+ const body = ['HEAD', 'GET'].includes(method)? null: self.body_content
+ self.promise()
+ fetch(url, {
+ body: body,
+ method: method,
+ headers: headers
+ })
.then((response) => {
self.set('ok', response.ok)
self.set('status', response.status)
diff --git a/src/lib/engine/http.lua b/src/lib/engine/http.lua
index 7bad3ec..ec27566 100644
--- a/src/lib/engine/http.lua
+++ b/src/lib/engine/http.lua
@@ -19,16 +19,16 @@ local function body(self, content)
end
local function param(self, name, value)
- local index = #self.param_name_list + 1
- self.param_name_list[index] = name
- self.param_value_list[index] = value
+ local index = #self.param_list + 1
+ self.param_list[index] = name
+ self.param_dict[name] = value
return self
end
local function header(self, name, value)
- local index = #self.header_name_list + 1
- self.header_name_list[index] = name
- self.header_value_list[index] = value
+ local index = #self.header_list + 1
+ self.header_list[index] = name
+ self.header_dict[name] = value
return self
end
@@ -65,10 +65,10 @@ local function request(method, std, game, application, protocol_handler)
speed = '',
method = method,
body_content = '',
- header_name_list = {},
- header_value_list = {},
- param_name_list = {},
- param_value_list = {},
+ header_list = {},
+ header_dict = {},
+ param_list = {},
+ param_dict = {},
callback_handler = callback_handler,
success_handler = function () end,
failed_handler = function () end,
@@ -127,14 +127,27 @@ local function request(method, std, game, application, protocol_handler)
self.std.http.error = nil
self.std.http.status = nil
end,
+ -- clean lists
+ function()
+ local index = 1
+ while index <= #self.param_list do
+ self.param_dict[self.param_list[index]] = nil
+ index = index + 1
+ end
+ index = 1
+ while index <= #self.header_list do
+ self.header_dict[self.header_list[index]] = nil
+ index = index + 1
+ end
+ end,
-- clean gc
function()
self.url = nil
self.body_content = nil
- self.param_name_list = nil
- self.param_value_list = nil
- self.header_name_list = nil
- self.header_value_list = nil
+ self.param_list = nil
+ self.param_dict = nil
+ self.header_list = nil
+ self.header_dict = nil
self.success_handler = nil
self.failed_handler = nil
self.std = nil
@@ -169,7 +182,6 @@ local function install(std, game, application, protocol)
std.http.put=request('PUT', std, game, application, protocol_handler)
std.http.delete=request('DELETE', std, game, application, protocol_handler)
std.http.patch=request('PATCH', std, game, application, protocol_handler)
-
if protocol.install then
protocol.install(std, game, application)
diff --git a/src/lib/protocol/http_curl.lua b/src/lib/protocol/http_curl.lua
index 387077f..6474653 100644
--- a/src/lib/protocol/http_curl.lua
+++ b/src/lib/protocol/http_curl.lua
@@ -1,16 +1,23 @@
+--! @todo support Body content in post
+local http_util = require('src/lib/util/http')
+
local function http_handler(self)
local index = 1
local cmd = 'curl -L --silent --insecure -w "\n%{http_code}" '
local protocol = self.method == 'HEAD' and '--HEAD' or '-X '..self.method
+ local params = http_util.url_search_param(self.param_list, self.param_dict)
local headers, index = ' ', 1
- while self.header_name_list and index <= #self.header_name_list do
- headers = headers..'-H "'..self.header_name_list[index]..': '
- headers = headers..self.header_value_list[index]..'" '
+
+ while self.header_list and index <= #self.header_list do
+ local header = self.header_list[index]
+ headers = headers..'-H "'..header..': '
+ headers = headers..self.header_dict[self.header_list[index]]..'" '
index = index + 1
end
- local handle = io and io.popen and io.popen(cmd..protocol..headers..self.url)
+
+ local handle = io and io.popen and io.popen(cmd..protocol..headers..self.url..params)
if handle then
local stdout = handle:read("*a")
diff --git a/src/lib/protocol/http_ginga.lua b/src/lib/protocol/http_ginga.lua
index 98afabd..9e6a2a9 100644
--- a/src/lib/protocol/http_ginga.lua
+++ b/src/lib/protocol/http_ginga.lua
@@ -80,14 +80,16 @@ local http_util = require('src/lib/util/http')
--! @cond
local function http_connect(self)
- local request = 'GET '..self.p_uri..' HTTP/1.1\r\n'
- ..'Host: '..self.p_host..'\r\n'
- ..'User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95; Win 9x 4.90)\r\n'
- ..'Cache-Control: max-age=0\r\n'
- ..'Accept: */*\r\n'
- ..'Content-Length: '..tostring(#self.body_content)..'\r\n'
- ..'Connection: close\r\n\r\n'
- ..self.body_content..'\r\n\r\n'
+ local params = http_util.url_search_param(self.param_list, self.param_dict)
+ local headers = http_util.headers(self.header_list, self.header_dict, {
+ 'Host', self.p_host..params, false,
+ 'Accept', '*/*', true,
+ 'Cache-Control', 'max-age=0', false,
+ 'User-Agent', 'Mozilla/4.0 (compatible; MSIE 4.0; Windows 95; Win 9x 4.90)', true,
+ 'Content-Length', tostring(#self.body_content), false,
+ 'Connection', 'close', false
+ })
+ local request = 'GET '..self.p_uri..' HTTP/1.1\r\n'..headers..'\r\n'..self.body_content..'\r\n\r\n'
event.post({
class = 'tcp',
@@ -101,7 +103,7 @@ end
--! @cond
local function http_connect_dns(self)
if self.p_host == self.evt.host then
- self.application.internal.dns_state = 2
+ self.application.internal.http.dns_state = 2
else
self.application.internal.http.context.dns(self)
self.application.internal.http.dns_state = 3
@@ -397,11 +399,9 @@ local function event_loop(std, game, application, evt)
local value = tostring(evt.value)
local debug = evt.type..' '..tostring(evt.host)..' '..tostring(evt.connection)..' '..value:sub(1, (value:find('\n') or 30) - 2)
- --game._debug = debug..'\r\n\r\n'..game._debug
if self then
local index = 'http_'..self.evt.type..self.speed
- --game._debug = index..'\r\n'..game._debug
application.internal.http.callbacks[index](self)
end
end
diff --git a/src/lib/util/http.lua b/src/lib/util/http.lua
index 9ae9b54..1d77614 100644
--- a/src/lib/util/http.lua
+++ b/src/lib/util/http.lua
@@ -6,7 +6,56 @@ local function is_redirect(status)
return (status and 300 <= status and status < 400) or false
end
+local function url_search_param(param_list, param_dict)
+ local index, params = 1, ''
+ while param_list and param_dict and index <= #param_list do
+ local param = param_list[index]
+ if #params == 0 then
+ params = param..'?'
+ else
+ params = param..'&'
+ end
+ params = params..param..'='..param_dict[param_list[index]]
+ index = index + 1
+ end
+ return params
+end
+
+--! @todo document this function
+local function headers(header_list, header_dict, config)
+ local headers = ''
+
+ if not header_list or not header_dict then
+ header_list = {}
+ header_dict = {}
+ end
+
+ local index = 1
+ while index <= #config do
+ local header = config[index]
+ local default = config[index + 1]
+ local mutable = config[index + 2]
+ local value = default
+ if mutable then
+ value = header_dict[header] or default
+ end
+ headers = headers..header..': '..value..'\r\n'
+ index = index + 3
+ end
+
+ local index = 1
+ while index <= #header_list do
+ local header = header_list[index]
+ headers = headers..header..': '..header_dict[header]..'\r\n'
+ index = index + 1
+ end
+
+ return headers
+end
+
return {
is_ok=is_ok,
- is_redirect=is_redirect
+ is_redirect=is_redirect,
+ url_search_param=url_search_param,
+ headers=headers
}
diff --git a/tests/test_lib_common_http.lua b/tests/test_lib_common_http.lua
index ccf85fa..d82dd2b 100644
--- a/tests/test_lib_common_http.lua
+++ b/tests/test_lib_common_http.lua
@@ -12,10 +12,10 @@ local http_handler = mock_http.requests({
['example.com/set-status-body-param1-param2'] = {
ok = true,
status = function(http_object)
- return http_object.param_value_list[1]
+ return http_object.param_dict[http_object.param_list[1]]
end,
body = function(http_object)
- return http_object.param_value_list[2]
+ return http_object.param_dict[http_object.param_list[2]]
end
},
['example.com/set-body-lower-with-body'] = {
diff --git a/tests/test_lib_protocol_http_curl.lua b/tests/test_lib_protocol_http_curl.lua
index 4093726..5d08466 100644
--- a/tests/test_lib_protocol_http_curl.lua
+++ b/tests/test_lib_protocol_http_curl.lua
@@ -11,6 +11,10 @@ local mock_popen = mock_io.open({
read=function () return 'method not allowed!\n403' end,
close=function () return true, nil end
},
+ ['curl -L --silent --insecure -w "\n%{http_code}" -X POST pudim.com.brz&z=zoom'] = {
+ read=function () return 'me too!\n201' end,
+ close=function () return true, nil end
+ },
['curl -L --silent --insecure -w "\n%{http_code}" --HEAD '] = {
read=function () return '' end,
close=function () return false, 'no URL specified!' end
@@ -33,14 +37,36 @@ function test_http_get_200()
luaunit.assertEquals(std.http.body, 'i love pudim!\n')
end
+function test_http_post_201()
+ local std = {http={}}
+ io.popen = mock_popen
+
+ protocol_http.handler({
+ std = std,
+ param_list = {'foo', 'bar', 'z'},
+ param_dict = {
+ ['foo'] = 'zig',
+ ['bar'] = 'zag',
+ ['z'] = 'zoom'
+ },
+ url = 'pudim.com.br',
+ method = 'POST'
+ })
+
+ luaunit.assertEquals(std.http.ok, true)
+ luaunit.assertEquals(std.http.error, nil)
+ luaunit.assertEquals(std.http.status, 201)
+ luaunit.assertEquals(std.http.body, 'me too!\n')
+end
+
function test_http_post_403()
local std = {http={}}
io.popen = mock_popen
protocol_http.handler({
std = std,
- header_name_list = {'Authorization'},
- header_value_list = {'bearer secret'},
+ header_list = {'Authorization'},
+ header_dict = {['Authorization'] = 'bearer secret'},
url = 'pudim.com.br',
method = 'POST'
})