diff --git a/services/web/app/coffee/infrastructure/ProxyManager.coffee b/services/web/app/coffee/infrastructure/ProxyManager.coffee index 4d64b25bae..3e7a037054 100644 --- a/services/web/app/coffee/infrastructure/ProxyManager.coffee +++ b/services/web/app/coffee/infrastructure/ProxyManager.coffee @@ -7,14 +7,20 @@ module.exports = ProxyManager = apply: (publicApiRouter) -> for proxyUrl, target of settings.proxyUrls do (target) -> - publicApiRouter.get proxyUrl, ProxyManager.createProxy(target) + method = target.options?.method || 'get' + publicApiRouter[method] proxyUrl, ProxyManager.createProxy(target) createProxy: (target) -> (req, res, next) -> targetUrl = makeTargetUrl(target, req) logger.log targetUrl: targetUrl, reqUrl: req.url, "proxying url" - upstream = request(targetUrl) + options = + url: targetUrl + options.headers = { Cookie: req.headers.cookie } if req.headers?.cookie + Object.assign(options, target.options) if target?.options? + options.form = req.body if options.method in ['post', 'put'] + upstream = request(options) upstream.on "error", (error) -> logger.error err: error, "error in ProxyManager" diff --git a/services/web/test/unit/coffee/infrastructure/ProxyManagerTests.coffee b/services/web/test/unit/coffee/infrastructure/ProxyManagerTests.coffee index 3f1c1e9f78..9a1d9ea17c 100644 --- a/services/web/test/unit/coffee/infrastructure/ProxyManagerTests.coffee +++ b/services/web/test/unit/coffee/infrastructure/ProxyManagerTests.coffee @@ -35,11 +35,26 @@ describe "ProxyManager", -> assertCalledWith(@router.get, '/foo/bar') assertCalledWith(@router.get, '/foo/:id') + it 'applies methods other than get', -> + @router = + post: sinon.stub() + put: sinon.stub() + @settings.proxyUrls = + '/foo/bar': {options: {method: 'post'}} + '/foo/:id': {options: {method: 'put'}} + @proxyManager.apply(@router) + sinon.assert.calledOnce(@router.post) + sinon.assert.calledOnce(@router.put) + assertCalledWith(@router.post, '/foo/bar') + assertCalledWith(@router.put, '/foo/:id') + describe 'createProxy', -> beforeEach -> @req.url = @proxyPath @req.route.path = @proxyPath @req.query = {} + @req.params = {} + @req.headers = {} @settings.proxyUrls = {} afterEach -> @@ -57,7 +72,7 @@ describe "ProxyManager", -> targetUrl = 'https://user:pass@foo.bar:123/pa/th.ext?query#hash' @settings.proxyUrls[@proxyPath] = targetUrl @proxyManager.createProxy(targetUrl)(@req) - assertCalledWith(@request, targetUrl) + assertCalledWith(@request, {url: targetUrl}) it 'overwrite query', -> targetUrl = 'foo.bar/baz?query' @@ -65,19 +80,19 @@ describe "ProxyManager", -> @settings.proxyUrls[@proxyPath] = targetUrl @proxyManager.createProxy(targetUrl)(@req) newTargetUrl = 'foo.bar/baz?requestQuery=important' - assertCalledWith(@request, newTargetUrl) + assertCalledWith(@request, {url: newTargetUrl}) it 'handles target objects', -> target = { baseUrl: 'api.v1', path: '/pa/th'} @settings.proxyUrls[@proxyPath] = target @proxyManager.createProxy(target)(@req, @res, @next) - assertCalledWith(@request, 'api.v1/pa/th') + assertCalledWith(@request, {url: 'api.v1/pa/th'}) it 'handles missing baseUrl', -> target = { path: '/pa/th'} @settings.proxyUrls[@proxyPath] = target @proxyManager.createProxy(target)(@req, @res, @next) - assertCalledWith(@request, 'undefined/pa/th') + assertCalledWith(@request, {url: 'undefined/pa/th'}) it 'handles dynamic path', -> target = baseUrl: 'api.v1', path: (params) -> "/resource/#{params.id}" @@ -86,4 +101,49 @@ describe "ProxyManager", -> @req.route.path = '/res/:id' @req.params = id: 123 @proxyManager.createProxy(target)(@req, @res, @next) - assertCalledWith(@request, 'api.v1/resource/123') + assertCalledWith(@request, {url: 'api.v1/resource/123'}) + + it 'set arbitrary options on request', -> + target = baseUrl: 'api.v1', path: '/foo', options: foo: 'bar' + @req.url = '/foo' + @req.route.path = '/foo' + @proxyManager.createProxy(target)(@req, @res, @next) + assertCalledWith(@request, + foo: 'bar' + url: 'api.v1/foo' + ) + + it 'passes cookies', -> + target = baseUrl: 'api.v1', path: '/foo' + @req.url = '/foo' + @req.route.path = '/foo' + @req.headers = cookie: 'cookie' + @proxyManager.createProxy(target)(@req, @res, @next) + assertCalledWith(@request, + headers: Cookie: 'cookie' + url: 'api.v1/foo' + ) + + it 'passes body for post', -> + target = baseUrl: 'api.v1', path: '/foo', options: method: 'post' + @req.url = '/foo' + @req.route.path = '/foo' + @req.body = foo: 'bar' + @proxyManager.createProxy(target)(@req, @res, @next) + assertCalledWith(@request, + form: foo: 'bar' + method: 'post' + url: 'api.v1/foo' + ) + + it 'passes body for put', -> + target = baseUrl: 'api.v1', path: '/foo', options: method: 'put' + @req.url = '/foo' + @req.route.path = '/foo' + @req.body = foo: 'bar' + @proxyManager.createProxy(target)(@req, @res, @next) + assertCalledWith(@request, + form: foo: 'bar' + method: 'put' + url: 'api.v1/foo' + ) \ No newline at end of file