diff --git a/kong-0.2.1-1.rockspec b/kong-0.2.1-1.rockspec index 1b8984afb03..b3d9ee1799c 100644 --- a/kong-0.2.1-1.rockspec +++ b/kong-0.2.1-1.rockspec @@ -12,20 +12,22 @@ description = { } dependencies = { "lua ~> 5.1", + "luasec ~> 0.5-2", "uuid ~> 0.2-1", "luatz ~> 0.3-1", "yaml ~> 1.1.1-1", - "luasec ~> 0.5-2", "lapis ~> 1.1.0-1", "stringy ~> 0.4-1", "cassandra ~> 0.5-7", + "multipart ~> 0.1-2", "lua-path ~> 0.2.3-1", "lua-cjson ~> 2.1.0-1", - "luasocket ~> 2.0.2-5", "ansicolors ~> 1.0.2-3", + + "luasocket ~> 2.0.2-5", "lrexlib-pcre ~> 2.7.2-1", - "multipart ~> 0.1-2" + "lua-llthreads2 ~> 0.1.3-1" } build = { type = "builtin", diff --git a/kong/dao/cassandra/base_dao.lua b/kong/dao/cassandra/base_dao.lua index a6aeae8dce1..ad1285b1dd7 100644 --- a/kong/dao/cassandra/base_dao.lua +++ b/kong/dao/cassandra/base_dao.lua @@ -14,7 +14,6 @@ local stringy = require "stringy" local Object = require "classic" local utils = require "kong.tools.utils" local uuid = require "uuid" -local rex = require "rex_pcre" local cassandra_constants = require "cassandra.constants" local error_types = constants.DATABASE_ERROR_TYPES @@ -183,9 +182,10 @@ function BaseDao:_close_session(session) end end -local pattern = "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" +local digit = "[0-9a-f]" +local uuid_pattern = "^"..table.concat({ digit:rep(8), digit:rep(4), digit:rep(4), digit:rep(4), digit:rep(12) }, '%-').."$" local function is_valid_uuid(uuid) - return rex.match(uuid, pattern) ~= nil + return uuid and uuid:match(uuid_pattern) ~= nil end -- Build the array of arguments to pass to lua-resty-cassandra :execute method. diff --git a/kong/dao/schemas.lua b/kong/dao/schemas.lua index ddb1797ac2f..d7b030abb3c 100644 --- a/kong/dao/schemas.lua +++ b/kong/dao/schemas.lua @@ -1,4 +1,3 @@ -local rex = require "rex_pcre" local utils = require "kong.tools.utils" local constants = require "kong.constants" @@ -69,7 +68,7 @@ function _M.validate(t, schema, is_update) -- Check field against a regex if specified elseif t[column] ~= nil and v.regex then - if not rex.match(t[column], v.regex) then + if not ngx.re.match(t[column], v.regex) then errors = utils.add_error(errors, column, column.." has an invalid value") end @@ -109,7 +108,7 @@ function _M.validate(t, schema, is_update) end -- Check for unexpected fields in the entity - for k,v in pairs(t) do + for k, v in pairs(t) do if schema[k] == nil then errors = utils.add_error(errors, k, k.." is an unknown field") end diff --git a/kong/tools/faker.lua b/kong/tools/faker.lua index 986ec1ca0b2..d7d55f7f2c5 100644 --- a/kong/tools/faker.lua +++ b/kong/tools/faker.lua @@ -29,9 +29,9 @@ Faker.FIXTURES = { { name = "API TESTS 3", public_dns = "test3.com", target_url = "http://mockbin.com" }, { name = "API TESTS 4", public_dns = "test4.com", target_url = "http://mockbin.com" }, { name = "API TESTS 5", public_dns = "test5.com", target_url = "http://mockbin.com" }, - { name = "API TESTS 6", public_dns = "cors1.com", target_url = "http://mockbin.com" }, { name = "API TESTS 7", public_dns = "cors2.com", target_url = "http://mockbin.com" }, + { name = "API TESTS 8 (logging)", public_dns = "logging.com", target_url = "http://mockbin.com" }, { name = "API TESTS 8 (dns)", public_dns = "dns1.com", target_url = "http://127.0.0.1:7771" }, { name = "API TESTS 9 (dns)", public_dns = "dns2.com", target_url = "http://localhost:7771" }, @@ -53,9 +53,6 @@ Faker.FIXTURES = { plugin_configuration = { -- API 1 { name = "keyauth", value = { key_names = { "apikey" }}, __api = 1 }, - { name = "tcplog", value = { host = "127.0.0.1", port = 7777 }, __api = 1 }, - { name = "udplog", value = { host = "127.0.0.1", port = 8888 }, __api = 1 }, - { name = "filelog", value = {}, __api = 1 }, -- API 2 { name = "basicauth", value = {}, __api = 2 }, -- API 3 @@ -80,7 +77,11 @@ Faker.FIXTURES = { headers = "origin, type, accepts", exposed_headers = "x-auth-token", max_age = 23, - credentials = true }, __api = 7 } + credentials = true }, __api = 7 }, + -- API 8 + { name = "tcplog", value = { host = "127.0.0.1", port = 7777 }, __api = 8 }, + { name = "udplog", value = { host = "127.0.0.1", port = 8888 }, __api = 8 }, + { name = "filelog", value = {}, __api = 8 }, } } diff --git a/kong/tools/http_client.lua b/kong/tools/http_client.lua index aba87e9d605..b5a92d5d56f 100644 --- a/kong/tools/http_client.lua +++ b/kong/tools/http_client.lua @@ -5,44 +5,6 @@ local cjson = require "cjson" local _M = {} --- Builds a querystring from a table, separated by `&` --- @param tab The key/value parameters --- @param key The parent key if the value is multi-dimensional (optional) --- @return a string representing the built querystring -local function build_query(tab, key) - if ngx then - return ngx.encode_args(tab) - else - local query = {} - local keys = {} - - for k in pairs(tab) do - keys[#keys+1] = k - end - - table.sort(keys) - - for _,name in ipairs(keys) do - local value = tab[name] - if key then - name = string.format("%s[%s]", tostring(key), tostring(name)) - end - if type(value) == "table" then - query[#query+1] = build_query(value, name) - else - value = tostring(value) - if value ~= "" then - query[#query+1] = string.format("%s=%s", name, value) - else - query[#query+1] = name - end - end - end - - return table.concat(query, "&") - end -end - local function http_call(options) -- Set Host header accordingly if not options.headers["host"] then @@ -67,7 +29,7 @@ function _M.get(url, querystring, headers) if not headers then headers = {} end if querystring then - url = string.format("%s?%s", url, build_query(querystring)) + url = string.format("%s?%s", url, ngx.encode_args(querystring)) end return http_call { @@ -82,7 +44,7 @@ function _M.post(url, form, headers) if not headers then headers = {} end if not form then form = {} end - local body = build_query(form) + local body = ngx.encode_args(form) headers["content-length"] = string.len(body) if not headers["content-type"] then headers["content-type"] = "application/x-www-form-urlencoded" @@ -148,7 +110,7 @@ function _M.delete(url, querystring, headers) if not headers then headers = {} end if querystring then - url = string.format("%s?%s", url, build_query(querystring)) + url = string.format("%s?%s", url, ngx.encode_args(querystring)) end return http_call { @@ -163,7 +125,7 @@ function _M.options(url, querystring, headers) if not headers then headers = {} end if querystring then - url = string.format("%s?%s", url, build_query(querystring)) + url = string.format("%s?%s", url, ngx.encode_args(querystring)) end return http_call { @@ -173,4 +135,4 @@ function _M.options(url, querystring, headers) } end -return _M \ No newline at end of file +return _M diff --git a/kong/tools/io.lua b/kong/tools/io.lua index dba1d6557ad..d3e58f2b3aa 100644 --- a/kong/tools/io.lua +++ b/kong/tools/io.lua @@ -1,7 +1,7 @@ -local constants = require "kong.constants" -local path = require("path").new("/") local yaml = require "yaml" +local path = require("path").new("/") local stringy = require "stringy" +local constants = require "kong.constants" local _M = {} diff --git a/spec/integration/proxy/realip_spec.lua b/spec/integration/proxy/realip_spec.lua index 967ec75380a..25f8e971be3 100644 --- a/spec/integration/proxy/realip_spec.lua +++ b/spec/integration/proxy/realip_spec.lua @@ -5,7 +5,6 @@ local yaml = require "yaml" local IO = require "kong.tools.io" local stringy = require "stringy" local uuid = require "uuid" -local rex = require "rex_pcre" -- This is important to seed the UUID generator uuid.seed() @@ -29,10 +28,16 @@ describe("Real IP", function() local uuid,_ = string.gsub(uuid(), "-", "") -- Making the request - local response, status, headers = http_client.get(STUB_GET_URL, {apikey = "apikey123"}, {host = "test1.com", ["X-Forwarded-For"] = "4.4.4.4, 1.1.1.1, 5.5.5.5", file_log_uuid = uuid}) + local response, status = http_client.get(STUB_GET_URL, nil, + { + host = "logging.com", + ["X-Forwarded-For"] = "4.4.4.4, 1.1.1.1, 5.5.5.5", + file_log_uuid = uuid + } + ) assert.are.equal(200, status) - -- Reading the log file and finding the entry + -- Reading the log file and finding the line with the entry local configuration = yaml.load(IO.read_file(TEST_CONF)) assert.truthy(configuration) local error_log = IO.read_file(configuration.nginx_working_dir.."/logs/error.log") @@ -46,18 +51,11 @@ describe("Real IP", function() end assert.truthy(line) - -- Matching the Json - local iterator, iter_err = rex.gmatch(line, "\\s+({.+})\\s+") - if not iterator then - error(iter_err) - end - local m, err = iterator() - if err then - error(err) - end - assert.truthy(m) + -- Retrieve the JSON part of the line + local json_str = line:match("(%{.*%})") + assert.truthy(json_str) - local log_message = cjson.decode(m) + local log_message = cjson.decode(json_str) assert.are.same("4.4.4.4", log_message.ip) assert.are.same(uuid, log_message.request.headers.file_log_uuid) end) diff --git a/spec/ngx_stub.lua b/spec/ngx_stub.lua new file mode 100644 index 00000000000..d65bebce505 --- /dev/null +++ b/spec/ngx_stub.lua @@ -0,0 +1,41 @@ +local reg = require "rex_pcre" + +_G.ngx = { + time = function() return os.time() end, -- cassandra.lua + re = { + match = reg.match + }, + -- Builds a querystring from a table, separated by `&` + -- @param tab The key/value parameters + -- @param key The parent key if the value is multi-dimensional (optional) + -- @return a string representing the built querystring + encode_args = function(tab, key) + local query = {} + local keys = {} + + for k in pairs(tab) do + keys[#keys+1] = k + end + + table.sort(keys) + + for _, name in ipairs(keys) do + local value = tab[name] + if key then + name = string.format("%s[%s]", tostring(key), tostring(name)) + end + if type(value) == "table" then + query[#query+1] = build_query(value, name) + else + value = tostring(value) + if value ~= "" then + query[#query+1] = string.format("%s=%s", name, value) + else + query[#query+1] = name + end + end + end + + return table.concat(query, "&") + end +} diff --git a/spec/plugins/logging_spec.lua b/spec/plugins/logging_spec.lua index f24165c8bf2..ca62f998798 100644 --- a/spec/plugins/logging_spec.lua +++ b/spec/plugins/logging_spec.lua @@ -6,7 +6,6 @@ local yaml = require "yaml" local IO = require "kong.tools.io" local uuid = require "uuid" local stringy = require "stringy" -local rex = require "rex_pcre" -- This is important to seed the UUID generator uuid.seed() @@ -64,7 +63,7 @@ describe("Logging Plugins", function() local thread = start_tcp_server() -- Starting the mock TCP server -- Making the request - local response, status, headers = http_client.get(STUB_GET_URL, {apikey = "apikey123"}, {host = "test1.com"}) + local response, status, headers = http_client.get(STUB_GET_URL, nil, { host = "logging.com" }) assert.are.equal(200, status) -- Getting back the TCP server input @@ -81,7 +80,7 @@ describe("Logging Plugins", function() local thread = start_udp_server() -- Starting the mock TCP server -- Making the request - local response, status, headers = http_client.get(STUB_GET_URL, {apikey = "apikey123"}, {host = "test1.com"}) + local response, status = http_client.get(STUB_GET_URL, nil, { host = "logging.com" }) assert.are.equal(200, status) -- Getting back the TCP server input @@ -95,13 +94,15 @@ describe("Logging Plugins", function() end) it("should log to file", function() - local uuid,_ = string.gsub(uuid(), "-", "") + local uuid = string.gsub(uuid(), "-", "") -- Making the request - local response, status, headers = http_client.get(STUB_GET_URL, {apikey = "apikey123"}, {host = "test1.com", file_log_uuid = uuid}) + local response, status = http_client.get(STUB_GET_URL, nil, + { host = "logging.com", file_log_uuid = uuid } + ) assert.are.equal(200, status) - -- Reading the log file and finding the entry + -- Reading the log file and finding the line with the entry local configuration = yaml.load(IO.read_file(TEST_CONF)) assert.truthy(configuration) local error_log = IO.read_file(configuration.nginx_working_dir.."/logs/error.log") @@ -115,22 +116,14 @@ describe("Logging Plugins", function() end assert.truthy(line) - -- Matching the Json - local iterator, iter_err = rex.gmatch(line, "\\s+({.+})\\s+") - if not iterator then - error(iter_err) - end - local m, err = iterator() - if err then - error(err) - end - assert.truthy(m) + -- Retrieve the JSON part of the line + local json_str = line:match("(%{.*%})") + assert.truthy(json_str) - local log_message = cjson.decode(m) + local log_message = cjson.decode(json_str) assert.are.same("127.0.0.1", log_message.ip) assert.are.same(uuid, log_message.request.headers.file_log_uuid) end) end) - end) diff --git a/spec/spec_helpers.lua b/spec/spec_helpers.lua index de1c21d60ad..6a4df2a2b12 100644 --- a/spec/spec_helpers.lua +++ b/spec/spec_helpers.lua @@ -13,6 +13,8 @@ local TEST_CONF_FILE = "kong_TEST.yml" local TEST_PROXY_URL = "http://localhost:8100" local TEST_API_URL = "http://localhost:8101" +require "spec.ngx_stub" + local _M = {} _M.API_URL = TEST_API_URL diff --git a/spec/unit/schemas_spec.lua b/spec/unit/schemas_spec.lua index 20cebd11717..2dab5d4a132 100644 --- a/spec/unit/schemas_spec.lua +++ b/spec/unit/schemas_spec.lua @@ -2,6 +2,8 @@ local schemas = require "kong.dao.schemas" local constants = require "kong.constants" local validate = schemas.validate +require "spec.ngx_stub" + describe("Schemas", function() it("should alias lua types to database types", function() diff --git a/spec/unit/statics_spec.lua b/spec/unit/statics_spec.lua index 413fc886a8f..edbddcd47f7 100644 --- a/spec/unit/statics_spec.lua +++ b/spec/unit/statics_spec.lua @@ -31,7 +31,7 @@ describe("Static files", function() describe("Configuration", function() - it("should parse a correct configuration", function() + it("should equal to this template to make sure no errors are pushed in the default config", function() local configuration = IO.read_file(spec_helper.DEFAULT_CONF_FILE) assert.are.same([[ diff --git a/spec/unit/tools/faker_spec.lua b/spec/unit/tools/faker_spec.lua index 82726abbe74..76afbf27a15 100644 --- a/spec/unit/tools/faker_spec.lua +++ b/spec/unit/tools/faker_spec.lua @@ -2,7 +2,7 @@ local uuid = require "uuid" local Faker = require "kong.tools.faker" local DaoError = require "kong.dao.error" -describe("Faker #tools", function() +describe("Faker", function() local ENTITIES_TYPES = { "api", "consumer", "basicauth_credential", "keyauth_credential", "plugin_configuration" } @@ -78,7 +78,7 @@ describe("Faker #tools", function() it("should be possible to add some random entities complementing the default hard-coded ones", function() faker:seed(2000) assert.spy(faker.insert_from_table).was.called(2) - assert.spy(insert_spy).was.called(8027) -- 3*2000 + base entities + assert.spy(insert_spy).was.called(8028) -- 3*2000 + base entities end) it("should create relations between entities_to_insert and inserted entities", function() diff --git a/spec/unit/tools/http_client_spec.lua b/spec/unit/tools/http_client_spec.lua index 028fee2ab43..e2f1ae63d0a 100644 --- a/spec/unit/tools/http_client_spec.lua +++ b/spec/unit/tools/http_client_spec.lua @@ -1,6 +1,8 @@ local cjson = require "cjson" local http_client = require "kong.tools.http_client" +require "spec.ngx_stub" + describe("HTTP Client", function() describe("GET", function()