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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Decrease nginx timer resolution to improve performance and enable PCRE JIT [PR #543](https://github.com/3scale/apicast/pull/543)
- Moved `proxy_pass` into new internal location `@upstream` [PR #535](https://github.com/3scale/apicast/pull/535)
- Split 3scale authorization to rewrite and access phase [PR #556](https://github.com/3scale/apicast/pull/556)
- Extract `mapping_rule` module from the `configuration` module [PR #571](https://github.com/3scale/apicast/pull/571)

## [3.2.0-alpha2] - 2017-11-30

Expand Down
68 changes: 2 additions & 66 deletions gateway/src/apicast/configuration.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ local _M = {
local len = string.len
local pairs = pairs
local type = type
local error = error
local tostring = tostring
local next = next
local lower = string.lower
local insert = table.insert
local setmetatable = setmetatable
local re_match = ngx.re.match

local inspect = require 'inspect'
local re = require 'ngx.re'
local env = require 'resty.env'
local resty_url = require 'resty.url'
local util = require 'apicast.util'
local policy_chain = require 'apicast.policy_chain'
local mapping_rule = require 'apicast.mapping_rule'

local mt = { __index = _M, __tostring = function() return 'Configuration' end }

Expand All @@ -30,54 +28,6 @@ local function map(func, tbl)
return newtbl
end

local function regexpify(path)
return path:gsub('?.*', ''):gsub("{.-}", '([\\w_.-]+)'):gsub("%.", "\\.")
end

local regex_variable = '\\{[-\\w_]+\\}'

local function hash_to_array(hash)
local array = {}
for k,v in pairs(hash or {}) do
insert(array, { k, v })
end
return array
end

local function check_querystring_params(params, args)
local match = true

for i=1, #params do
local param = params[i][1]
local expected = params[i][2]
local m, err = re_match(expected, regex_variable, 'oj')
local value = args[param]

if m then
if not value then -- regex variable have to have some value
ngx.log(ngx.DEBUG, 'check query params ', param, ' value missing ', expected)
match = false
break
end
else
if err then ngx.log(ngx.ERR, 'check match error ', err) end

-- if many values were passed use the last one
if type(value) == 'table' then
value = value[#value]
end

if value ~= expected then -- normal variables have to have exact value
ngx.log(ngx.DEBUG, 'check query params does not match ', param, ' value ' , value, ' == ', expected)
match = false
break
end
end
end

return match
end

local Service = require 'apicast.configuration.service'

local noop = function() end
Expand Down Expand Up @@ -158,21 +108,7 @@ function _M.parse_service(service)
app_id = lower(proxy.auth_app_id or 'app_id'),
app_key = lower(proxy.auth_app_key or 'app_key') -- TODO: use App-Key if location is headers
},
rules = map(function(proxy_rule)
local querystring_parameters = hash_to_array(proxy_rule.querystring_parameters)

return {
method = proxy_rule.http_method,
pattern = proxy_rule.pattern,
regexpified_pattern = regexpify(proxy_rule.pattern),
parameters = proxy_rule.parameters,
querystring_params = function(args)
return check_querystring_params(querystring_parameters, args)
end,
system_name = proxy_rule.metric_system_name or error('missing metric name of rule ' .. inspect(proxy_rule)),
delta = proxy_rule.delta
}
end, proxy.proxy_rules or {}),
rules = map(mapping_rule.from_proxy_rule, proxy.proxy_rules or {}),

-- I'm not happy about this, but we need a way how to serialize back the object for the management API.
-- And returning the original back is the easiest option for now.
Expand Down
112 changes: 112 additions & 0 deletions gateway/src/apicast/mapping_rule.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
--- Mapping rule
-- @module mapping_rule
-- A mapping rule consists of a pattern used to match requests. It also defines
-- a metric and a value that indicates how to increase the usage of a metric
-- when there is a match.

local setmetatable = setmetatable
local pairs = pairs
local error = error
local type = type
local re_match = ngx.re.match
local insert = table.insert

local _M = {}

local mt = { __index = _M }

local function hash_to_array(hash)
local array = {}

for k,v in pairs(hash or {}) do
insert(array, { k, v })
end

return array
end

local function regexpify(path)
return path:gsub('?.*', ''):gsub("{.-}", '([\\w_.-]+)'):gsub("%.", "\\.")
end

local regex_variable = '\\{[-\\w_]+\\}'

local function check_querystring_params(params, args)
local match = true

for i=1, #params do
local param = params[i][1]
local expected = params[i][2]
local m, err = re_match(expected, regex_variable, 'oj')
local value = args[param]

if m then
if not value then -- regex variable have to have some value
ngx.log(ngx.DEBUG, 'check query params ', param,
' value missing ', expected)
match = false
break
end
else
if err then ngx.log(ngx.ERR, 'check match error ', err) end

-- if many values were passed use the last one
if type(value) == 'table' then
value = value[#value]
end

if value ~= expected then -- normal variables have to have exact value
ngx.log(ngx.DEBUG, 'check query params does not match ',
param, ' value ' , value, ' == ', expected)
match = false
break
end
end
end

return match
end

local function new(http_method, pattern, params, querystring_params, metric, delta)
local self = setmetatable({}, mt)

local querystring_parameters = hash_to_array(querystring_params)

self.method = http_method
self.pattern = pattern
self.regexpified_pattern = regexpify(pattern)
self.parameters = params
self.system_name = metric or error('missing metric name of rule')
self.delta = delta

self.querystring_params = function(args)
return check_querystring_params(querystring_parameters, args)
end

return self
end

--- Initializes a mapping rule from a proxy rule of the service configuration.
--
-- @tparam table proxy_rule Proxy rule from the service configuration.
-- @tfield string http_method HTTP method (GET, POST, etc.).
-- @tfield string pattern Pattern used to match a request.
-- @tfield table parameters Parameters of the pattern.
-- @tfield table querystring_parameters Table with the params of the request
-- and its values.
-- @tfield string metric_system_name Name of the metric.
-- @tfield integer delta The usage of the metric will be increased by this
-- value.
-- @treturn mapping_rule New mapping rule.
function _M.from_proxy_rule(proxy_rule)
return new(
proxy_rule.http_method,
proxy_rule.pattern,
proxy_rule.parameters,
proxy_rule.querystring_parameters,
proxy_rule.metric_system_name,
proxy_rule.delta
)
end

return _M