diff --git a/CHANGELOG.md b/CHANGELOG.md index 18505a8a8..187c15499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add the correct host header when using an http proxy [THREESCALE-4178](https://issues.jboss.org/browse/THREESCALE-4178) [PR #1143](https://github.com/3scale/APIcast/pull/1143) - Normalize policy names capitalization [THREESCALE-4150](https://issues.jboss.org/browse/THREESCALE-4150) [PR #1154](https://github.com/3scale/APIcast/pull/1154) - Fix issues with non-alphanumeric variables in liquid [THREESCALE-3968](https://issues.jboss.org/browse/THREESCALE-3968) [PR #1158](https://github.com/3scale/APIcast/pull/1158) +- Fix issues with double mapping rules [THREESCALE-3950](https://issues.jboss.org/browse/THREESCALE-3950) [PR #1159](https://github.com/3scale/APIcast/pull/1159) + ### Fixed diff --git a/gateway/src/apicast/mapping_rule.lua b/gateway/src/apicast/mapping_rule.lua index dd829b59d..a9d99e6e1 100644 --- a/gateway/src/apicast/mapping_rule.lua +++ b/gateway/src/apicast/mapping_rule.lua @@ -35,6 +35,11 @@ local function hash_to_array(hash) end local function regexpify(pattern) + -- some urls in APIAP uses double / that it's a valid url, but ngx.var.uri + -- eliminates the duplicates, so mapping rule needs to remove the duplicates + -- ones. + pattern = re_gsub(pattern,[[\/\/+]], '/', 'oj') + pattern = re_gsub(pattern, [[\?.*]], '', 'oj') -- dollar sign is escaped by another $, see https://github.com/openresty/lua-nginx-module#ngxresub pattern = re_gsub(pattern, [[\{.+?\}]], [[([\w-.~%!$$&'()*+,;=@:]+)]], 'oj') diff --git a/gateway/src/apicast/policy/soap/soap.lua b/gateway/src/apicast/policy/soap/soap.lua index b85ef7afd..358d12145 100644 --- a/gateway/src/apicast/policy/soap/soap.lua +++ b/gateway/src/apicast/policy/soap/soap.lua @@ -17,6 +17,7 @@ local MappingRule = require('apicast.mapping_rule') local Usage = require('apicast.usage') local mapping_rules_matcher = require('apicast.mapping_rules_matcher') local MimeType = require('resty.mime') +local resty_url = require 'resty.url' local policy = require('apicast.policy') @@ -90,6 +91,13 @@ end function _M:rewrite(context) local soap_action_uri = extract_soap_uri() + -- If the soap_action_uri is a complete url, the mapping rule is only the + -- path, so parse to send only the path. + local url, err = resty_url.parse(soap_action_uri) + if not err then + soap_action_uri = url.path + end + if soap_action_uri then local soap_usage = usage_from_matching_rules( soap_action_uri, self.mapping_rules) diff --git a/spec/mapping_rule_spec.lua b/spec/mapping_rule_spec.lua index e6a253724..9fd9be8fa 100644 --- a/spec/mapping_rule_spec.lua +++ b/spec/mapping_rule_spec.lua @@ -120,6 +120,29 @@ describe('mapping_rule', function() assert.is_true(mapping_rule:matches('GET', '/foo/a:b/bar')) assert.is_true(mapping_rule:matches('GET', "/foo/a%b/bar")) end) + + it('double slashes are transformed correctly to a simple one', function() + local test_cases = { + ["/foo//bar"] = "/foo/bar", + ["/foo///bar"] = "/foo/bar", + ["/foo/ /bar"] = "/foo/ /bar", + ["/foo/bar///"] = "/foo/bar/", + ["///foo///bar///"] = "/foo/bar/", + } + + for key, value in pairs(test_cases) do + local mapping_rule = MappingRule.from_proxy_rule({ + http_method = 'GET', + pattern = key, + querystring_parameters = { }, + metric_system_name = 'hits', + delta = 1 + }) + + assert.is_true(mapping_rule:matches('GET', value), "Invalid key:" .. key) + end + + end) end) describe('.any_method', function() diff --git a/spec/policy/soap/soap_spec.lua b/spec/policy/soap/soap_spec.lua index 09bf50a14..fddc667ff 100644 --- a/spec/policy/soap/soap_spec.lua +++ b/spec/policy/soap/soap_spec.lua @@ -4,9 +4,9 @@ describe('SOAP policy', function() describe('.rewrite', function() local context -- Context shared between policies - local full_url = "http://www.example.com:80/path/to/myfile.html?" .. - "key1=value1&key2=value2#SomewhereInTheDocument" - + local base_url = "http://www.example.com:80" + local base_path = "/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument" + local full_url = base_url .. base_path -- Define a config with 3 rules. Their patterns have values that allow us -- to easily associate them with a SOAP action receive via SOAPAction -- header or via Content-Type. The third one is used to tests matching of @@ -24,7 +24,7 @@ describe('SOAP policy', function() delta = 20 }, { - pattern = full_url, + pattern = base_path, metric_system_name = 'hits', delta = 30 },