-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Request transformation plugin and minor fixes
- Loading branch information
1 parent
2e3814d
commit 1388516
Showing
14 changed files
with
330 additions
and
10 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
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,130 @@ | ||
local stringy = require "stringy" | ||
local Multipart = require "multipart" | ||
|
||
local _M = {} | ||
|
||
local CONTENT_LENGTH = "content-length" | ||
local FORM_URLENCODED = "application/x-www-form-urlencoded" | ||
local MULTIPART_DATA = "multipart/form-data" | ||
local CONTENT_TYPE = "content-type" | ||
|
||
local function iterate_and_exec(val, cb) | ||
if utils.table_size(val) > 0 then | ||
for _, entry in ipairs(val) do | ||
local parts = stringy.split(entry, ":") | ||
cb(parts[1], utils.table_size(parts) == 2 and parts[2] or nil) | ||
end | ||
end | ||
end | ||
|
||
local function get_content_type(request) | ||
local header_value = ngx.req.get_headers()[CONTENT_TYPE] | ||
if header_value then | ||
return stringy.strip(header_value) | ||
end | ||
return nil | ||
end | ||
|
||
function _M.execute(conf) | ||
if not conf then return end | ||
|
||
if conf.add then | ||
|
||
-- Add headers | ||
if conf.add.headers then | ||
iterate_and_exec(conf.add.headers, function(name, value) | ||
ngx.req.set_header(name, value) | ||
end) | ||
end | ||
|
||
-- Add Querystring | ||
if conf.add.querystring then | ||
local querystring = ngx.req.get_uri_args() | ||
iterate_and_exec(conf.add.querystring, function(name, value) | ||
querystring[name] = value | ||
end) | ||
ngx.req.set_uri_args(querystring) | ||
end | ||
|
||
if conf.add.form then | ||
local content_type = get_content_type(ngx.req) | ||
if content_type and stringy.startswith(content_type, FORM_URLENCODED) then | ||
-- Call ngx.req.read_body to read the request body first | ||
-- or turn on the lua_need_request_body directive to avoid errors. | ||
ngx.req.read_body() | ||
|
||
local parameters = ngx.req.get_post_args() | ||
iterate_and_exec(conf.add.form, function(name, value) | ||
parameters[name] = value | ||
end) | ||
local encoded_args = ngx.encode_args(parameters) | ||
ngx.req.set_header(CONTENT_LENGTH, string.len(encoded_args)) | ||
ngx.req.set_body_data(encoded_args) | ||
elseif content_type and stringy.startswith(content_type, MULTIPART_DATA) then | ||
-- Call ngx.req.read_body to read the request body first | ||
-- or turn on the lua_need_request_body directive to avoid errors. | ||
ngx.req.read_body() | ||
|
||
local body = ngx.req.get_body_data() | ||
local parameters = Multipart(body and body or "", content_type) | ||
iterate_and_exec(conf.add.form, function(name, value) | ||
parameters:set_simple(name, value) | ||
end) | ||
local new_data = parameters:tostring() | ||
ngx.req.set_header(CONTENT_LENGTH, string.len(new_data)) | ||
ngx.req.set_body_data(new_data) | ||
end | ||
end | ||
|
||
end | ||
|
||
if conf.remove then | ||
|
||
-- Add headers | ||
if conf.remove.headers then | ||
iterate_and_exec(conf.remove.headers, function(name, value) | ||
ngx.req.clear_header(name) | ||
end) | ||
end | ||
|
||
if conf.remove.querystring then | ||
local querystring = ngx.req.get_uri_args() | ||
iterate_and_exec(conf.remove.querystring, function(name) | ||
querystring[name] = nil | ||
end) | ||
ngx.req.set_uri_args(querystring) | ||
end | ||
|
||
if conf.remove.form then | ||
local content_type = get_content_type(ngx.req) | ||
if content_type and stringy.startswith(content_type, FORM_URLENCODED) then | ||
local parameters = ngx.req.get_post_args() | ||
|
||
iterate_and_exec(conf.remove.form, function(name) | ||
parameters[name] = nil | ||
end) | ||
|
||
local encoded_args = ngx.encode_args(parameters) | ||
ngx.req.set_header(CONTENT_LENGTH, string.len(encoded_args)) | ||
ngx.req.set_body_data(encoded_args) | ||
elseif content_type and stringy.startswith(content_type, MULTIPART_DATA) then | ||
-- Call ngx.req.read_body to read the request body first | ||
-- or turn on the lua_need_request_body directive to avoid errors. | ||
ngx.req.read_body() | ||
|
||
local body = ngx.req.get_body_data() | ||
local parameters = Multipart(body and body or "", content_type) | ||
iterate_and_exec(conf.remove.form, function(name) | ||
parameters:delete(name) | ||
end) | ||
local new_data = parameters:tostring() | ||
ngx.req.set_header(CONTENT_LENGTH, string.len(new_data)) | ||
ngx.req.set_body_data(new_data) | ||
end | ||
end | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-- Copyright (C) Mashape, Inc. | ||
|
||
local BasePlugin = require "kong.plugins.base_plugin" | ||
local access = require "kong.plugins.request_transformer.access" | ||
|
||
local RequestTransformerHandler = BasePlugin:extend() | ||
|
||
function RequestTransformerHandler:new() | ||
RequestTransformerHandler.super.new(self, "request_transformer") | ||
end | ||
|
||
function RequestTransformerHandler:access(conf) | ||
RequestTransformerHandler.super.access(self) | ||
access.execute(conf) | ||
end | ||
|
||
RequestTransformerHandler.PRIORITY = 800 | ||
|
||
return RequestTransformerHandler |
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,16 @@ | ||
local constants = require "kong.constants" | ||
|
||
return { | ||
add = { require = "false", type = "table", schema = { | ||
form = { required = false, type = "table" }, | ||
headers = { required = false, type = "table" }, | ||
querystring = { required = false, type = "table" } | ||
} | ||
}, | ||
remove = { require = "false", type = "table", schema = { | ||
form = { required = false, type = "table" }, | ||
headers = { required = false, type = "table" }, | ||
querystring = { required = false, type = "table" } | ||
} | ||
} | ||
} |
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
104 changes: 104 additions & 0 deletions
104
spec/integration/proxy/request_transformer_plugin_spec.lua
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,104 @@ | ||
local spec_helper = require "spec.spec_helpers" | ||
local http_client = require "kong.tools.http_client" | ||
local cjson = require "cjson" | ||
|
||
STUB_GET_URL = spec_helper.STUB_GET_URL | ||
STUB_POST_URL = spec_helper.STUB_POST_URL | ||
|
||
describe("Request Transformer Plugin #proxy", function() | ||
|
||
setup(function() | ||
spec_helper.prepare_db() | ||
spec_helper.start_kong() | ||
end) | ||
|
||
teardown(function() | ||
spec_helper.stop_kong() | ||
spec_helper.reset_db() | ||
end) | ||
|
||
describe("Test adding parameters", function() | ||
|
||
it("should add new headers", function() | ||
local response, status, headers = http_client.get(STUB_GET_URL, {}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("true", body.headers["x-added"]) | ||
assert.are.equal("true", body.headers["x-added2"]) | ||
end) | ||
|
||
it("should add new parameters on POST", function() | ||
local response, status, headers = http_client.post(STUB_POST_URL, {}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("newvalue", body.postData.params["newformparam"]) | ||
end) | ||
|
||
it("should add new parameters on POST when existing params exist", function() | ||
local response, status, headers = http_client.post(STUB_POST_URL, { hello = "world" }, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("world", body.postData.params["hello"]) | ||
assert.are.equal("newvalue", body.postData.params["newformparam"]) | ||
end) | ||
|
||
it("should add new parameters on multipart POST", function() | ||
local response, status, headers = http_client.post_multipart(STUB_POST_URL, {}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("newvalue", body.postData.params["newformparam"]) | ||
end) | ||
|
||
it("should add new parameters on multipart POST when existing params exist", function() | ||
local response, status, headers = http_client.post_multipart(STUB_POST_URL, { hello = "world" }, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("world", body.postData.params["hello"]) | ||
assert.are.equal("newvalue", body.postData.params["newformparam"]) | ||
end) | ||
|
||
it("should add new parameters on GET", function() | ||
local response, status, headers = http_client.get(STUB_GET_URL, {}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.are.equal("value", body.queryString["newparam"]) | ||
end) | ||
|
||
end) | ||
|
||
describe("Test removing parameters", function() | ||
|
||
it("should remove a header", function() | ||
local response, status, headers = http_client.get(STUB_GET_URL, {}, {host = "test5.com", ["x-to-remove"] = "true"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.falsy(body.headers["x-to-remove"]) | ||
end) | ||
|
||
it("should remove parameters on POST", function() | ||
local response, status, headers = http_client.post(STUB_POST_URL, {["toremoveform"] = "yes", ["nottoremove"] = "yes"}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.falsy(body.postData.params["toremoveform"]) | ||
assert.are.same("yes", body.postData.params["nottoremove"]) | ||
end) | ||
|
||
it("should remove parameters on multipart POST", function() | ||
local response, status, headers = http_client.post_multipart(STUB_POST_URL, {["toremoveform"] = "yes", ["nottoremove"] = "yes"}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.falsy(body.postData.params["toremoveform"]) | ||
assert.are.same("yes", body.postData.params["nottoremove"]) | ||
end) | ||
|
||
it("should remove parameters on GET", function() | ||
local response, status, headers = http_client.get(STUB_GET_URL, {["toremovequery"] = "yes", ["nottoremove"] = "yes"}, {host = "test5.com"}) | ||
local body = cjson.decode(response) | ||
assert.are.equal(200, status) | ||
assert.falsy(body.queryString["toremovequery"]) | ||
assert.are.equal("yes", body.queryString["nottoremove"]) | ||
end) | ||
|
||
end) | ||
|
||
end) |
Oops, something went wrong.