-
Notifications
You must be signed in to change notification settings - Fork 169
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #724 from 3scale/querystring-ops-url-rewriting-policy
URL rewriting policy: Allow to modify query parameters
- Loading branch information
Showing
7 changed files
with
819 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
local setmetatable = setmetatable | ||
local insert = table.insert | ||
local type = type | ||
|
||
local _M = {} | ||
|
||
local mt = { __index = _M } | ||
|
||
-- Note: This module calls 'ngx.req.set_uri_args()' on each operation | ||
-- If this becomes too costly, we can change it by exposing a method that calls | ||
-- 'ngx.req.set_uri_args()' leaving that responsibility to the caller. | ||
|
||
--- Initialize a new QueryStringParams | ||
-- @tparam[opt] table uri_args URI arguments | ||
function _M.new(uri_args) | ||
local self = setmetatable({}, mt) | ||
|
||
if uri_args then | ||
self.args = uri_args | ||
else | ||
local get_args_err | ||
self.args, get_args_err = ngx.req.get_uri_args() | ||
|
||
if not self.args then | ||
ngx.log(ngx.ERR, 'Error while getting URI args: ', get_args_err) | ||
return nil, get_args_err | ||
end | ||
end | ||
|
||
return self | ||
end | ||
|
||
--- Updates the URI args | ||
local function update_uri_args(args) | ||
ngx.req.set_uri_args(args) | ||
end | ||
|
||
local function add_to_existing_arg(self, arg, value) | ||
-- When the argument has a single value, it is a string and needs to be | ||
-- converted to table so we can add a second one. | ||
if type(self.args[arg]) ~= 'table' then | ||
self.args[arg] = { self.args[arg] } | ||
end | ||
|
||
insert(self.args[arg], value) | ||
end | ||
|
||
--- Pushes a value to an argument | ||
-- 1) When the arg is not set, creates it with the given value. | ||
-- 2) When the arg is set, it adds a new value for it (becomes an array if it | ||
-- was not one already). | ||
function _M:push(arg, value) | ||
if not self.args[arg] then | ||
self.args[arg] = value | ||
else | ||
add_to_existing_arg(self, arg, value) | ||
end | ||
|
||
update_uri_args(self.args) | ||
end | ||
|
||
--- Set a value for an argument | ||
-- 1) When the arg is not set, creates it with the given value. | ||
-- 2) When the arg is set, replaces its value with the given one. | ||
function _M:set(arg, value) | ||
self.args[arg] = value | ||
update_uri_args(self.args) | ||
end | ||
|
||
--- Adds a value for an argument | ||
-- 1) When the arg is not set, it does nothing. | ||
-- 2) When the arg is set, it adds a new value for it (becomes an array if it | ||
-- was not one already). | ||
function _M:add(arg, value) | ||
if self.args[arg] then | ||
add_to_existing_arg(self, arg, value) | ||
update_uri_args(self.args) | ||
end | ||
end | ||
|
||
--- Deletes an argument | ||
function _M:delete(arg) | ||
if self.args[arg] then | ||
self.args[arg] = nil | ||
update_uri_args(self.args) | ||
end | ||
end | ||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
local QueryParams = require('apicast.policy.url_rewriting.query_params') | ||
|
||
describe('QueryParams', function() | ||
before_each(function() | ||
stub(ngx.req, 'set_uri_args') | ||
end) | ||
|
||
describe('.push', function() | ||
describe('if the arg is not in the query', function() | ||
it('creates it with the given value', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:push('b', '2') | ||
|
||
local expected_args = { a = '1', b = '2' } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
|
||
describe('if the arg is in the query', function() | ||
describe('and it has a single value', function() | ||
it('adds a new value for it', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:push('a', '2') | ||
|
||
local expected_args = { a = { '1', '2' } } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
|
||
describe('and it is an array', function() | ||
it('adds a new value for it', function() | ||
local params = QueryParams.new({ a = { '1', '2' } }) | ||
|
||
params:push('a', '3') | ||
|
||
local expected_args = { a = { '1', '2', '3' } } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
end) | ||
end) | ||
|
||
describe('.set', function() | ||
describe('if the arg is not in the query', function() | ||
it('creates it with the given value', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:set('b', '2') | ||
|
||
local expected_args = { a = '1', b = '2' } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
|
||
describe('if the arg is in the query', function() | ||
it('replaces its value with the given one', function() | ||
local params = QueryParams.new({ a = { '1', '2' } }) | ||
|
||
params:set('a', '3') | ||
|
||
local expected_args = { a = '3' } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
end) | ||
|
||
describe('.add', function() | ||
describe('if the arg is not in the query', function() | ||
it('does nothing', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:add('b', '2') | ||
|
||
assert.stub(ngx.req.set_uri_args).was_not_called() | ||
end) | ||
end) | ||
|
||
describe('if the arg is in the query', function() | ||
describe('and it has a single value', function() | ||
it('adds a new value for it', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:add('a', '2') | ||
|
||
local expected_args = { a = { '1', '2' } } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
|
||
describe('and it is an array', function() | ||
it('adds a new value for it', function() | ||
local params = QueryParams.new({ a = { '1', '2' } }) | ||
|
||
params:add('a', '3') | ||
|
||
local expected_args = { a = { '1', '2', '3' } } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
end) | ||
end) | ||
|
||
describe('.delete', function() | ||
describe('if the argument is in the query', function() | ||
it('deletes it', function() | ||
local params = QueryParams.new({ a = '1', b = '2' }) | ||
|
||
params:delete('a') | ||
|
||
local expected_args = { b = '2' } | ||
assert.stub(ngx.req.set_uri_args).was_called_with(expected_args) | ||
end) | ||
end) | ||
|
||
describe('if the argument is not in the query', function() | ||
it('does not delete anything', function() | ||
local params = QueryParams.new({ a = '1' }) | ||
|
||
params:delete('b') | ||
|
||
assert.stub(ngx.req.set_uri_args).was_not_called() | ||
end) | ||
end) | ||
end) | ||
end) |
Oops, something went wrong.