From 92a73a9cb3ddddbfcff43deb3c9a1bcb3f91ddbe Mon Sep 17 00:00:00 2001 From: Daria Mayorova Date: Wed, 16 May 2018 19:22:49 +0200 Subject: [PATCH] Support special characters for mapping rule wildcards in url path --- CHANGELOG.md | 1 + gateway/src/apicast/mapping_rule.lua | 4 +++- spec/mapping_rule_spec.lua | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e203f97c7..90aee7b8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Decoded JWTs are now exposed in the policies context by the APIcast policy [PR #718](https://github.com/3scale/apicast/pull/718) - Upgraded OpenResty to 1.13.6.2, uses OpenSSL 1.1 [PR #733](https://github.com/3scale/apicast/pull/733) - Use forked `resty.limit.count` that uses increments instead of decrements [PR #758](https://github.com/3scale/apicast/pull/758) +- The regular expression for mapping rules has been changed, so that special characters are accepted in the wildcard values for path [PR #717](https://github.com/3scale/apicast/pull/714) ### Fixed diff --git a/gateway/src/apicast/mapping_rule.lua b/gateway/src/apicast/mapping_rule.lua index 9a175dec3..98eef7b6b 100644 --- a/gateway/src/apicast/mapping_rule.lua +++ b/gateway/src/apicast/mapping_rule.lua @@ -27,7 +27,9 @@ local function hash_to_array(hash) end local function regexpify(pattern) - return pattern:gsub('?.*', ''):gsub("{.-}", '([\\w_.-]+)'):gsub("%.", "\\.") + -- as per the RFC: https://tools.ietf.org/html/rfc3986#section-3.3 + local wildcard_regex = [[([\w-.~%%!$&'()*+,;=@:]+)]] -- using long Lua brackets [[...]], escaping `%` + return pattern:gsub('?.*', ''):gsub("{.-}", wildcard_regex):gsub("%.", "\\.") end local regex_variable = '\\{[-\\w_]+\\}' diff --git a/spec/mapping_rule_spec.lua b/spec/mapping_rule_spec.lua index f95aba75e..39b11c966 100644 --- a/spec/mapping_rule_spec.lua +++ b/spec/mapping_rule_spec.lua @@ -79,5 +79,20 @@ describe('mapping_rule', function() local match = mapping_rule:matches('POST', '/def', { x = 'y' }) assert.is_false(match) end) + + it('returns true when wildcard value has special characters: @ : % etc.', function() + local mapping_rule = MappingRule.from_proxy_rule({ + http_method = 'GET', + pattern = '/foo/{wildcard}/bar', + querystring_parameters = { }, + metric_system_name = 'hits', + delta = 1 + }) + + assert.is_true(mapping_rule:matches('GET', '/foo/a@b/bar')) + assert.is_true(mapping_rule:matches('GET', '/foo/a:b/bar')) + assert.is_true(mapping_rule:matches('GET', "/foo/a%b/bar")) + end) + end) end)