Skip to content

Commit

Permalink
policy/soap: support all accepted formats in the content-type header …
Browse files Browse the repository at this point in the history
…value

Accepted formats defined here:
https://tools.ietf.org/html/rfc7231#section-3.1.1.1
  • Loading branch information
davidor committed Feb 8, 2018
1 parent 70bbb43 commit 5efc505
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
20 changes: 17 additions & 3 deletions gateway/src/apicast/policy/soap/soap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

local sub = string.sub
local len = string.len
local lower = string.lower
local ipairs = ipairs
local insert = table.insert
local re = require('ngx.re')
Expand Down Expand Up @@ -43,14 +44,25 @@ end
-- Content-Type header. The string has this format:
-- a_param=x;action=soap_action;another_param=y
-- This method returns the value of 'action' or nil when it's not present.
-- Note that params can be a mix of lower and upper case chars, it can have
-- spaces, and wrap the value with '"':
-- https://tools.ietf.org/html/rfc7231#section-3.1.1.1
local function soap_action_from_ctype_params(params)
local params_split = re.split(params, ";")
local params_without_blanks = ngx.re.gsub(params, '\\s', '')
local params_split = re.split(params_without_blanks, ";")

for _, param in ipairs(params_split) do
local header_param_split = re.split(param, "=")
local name = header_param_split[1]
local value = header_param_split[2]
if name == "action" then

-- Strip '"' if included
if sub(value, 1, 1) == '"' then
value = sub(value, 2, -2)
end

-- Lower because it can contain mix of lower and upper-case chars.
if lower(name) == "action" then
return value
end
end
Expand All @@ -64,7 +76,9 @@ end
local function soap_action_in_ctype(headers)
local ctype = headers['Content-Type']

if ctype and starts_with(ctype, soap_action_ctype) then
-- The Content-Type can be a mix of upper and lower-case chars. Convert it to
-- include only lower-case chars to be able to compare it.
if ctype and starts_with(lower(ctype), soap_action_ctype) then
local header_params = sub(ctype, len(soap_action_ctype) + 1, -1)
return soap_action_from_ctype_params(header_params)
else
Expand Down
27 changes: 27 additions & 0 deletions spec/policy/soap/policy_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,33 @@ describe('policy', function()
assert.equals(21, context.usage.deltas['hits'])
end)
end)

describe('and the params contain some upper-case chars or spaces', function()
it('calculates the usage and merges it with the one in the context', function()
local header_vals = {
-- Upper-case chars in type/subtype
"Application/SOAP+xml;action=/soap_action_ctype",
-- Upper-case chars in 'Action'
"application/soap+xml;Action=/soap_action_ctype",
-- "" in action value
'application/soap+xml;action="/soap_action_ctype"',
-- Spaces
"application/soap+xml; action=/soap_action_ctype; a_param=x"
}

for _, header_val in ipairs(header_vals) do
ngx.req.get_headers = function()
return { ["Content-Type"] = header_val }
end

context = { usage = Usage.new() }
context.usage:add('hits', 1)
soap_policy:rewrite(context)

assert.equals(21, context.usage.deltas['hits'])
end
end)
end)
end)

describe('when the SOAP action is in the SOAPAction and the Content-Type headers', function()
Expand Down

0 comments on commit 5efc505

Please sign in to comment.