diff --git a/lib/index.js b/lib/index.js index 02631e4..d287282 100755 --- a/lib/index.js +++ b/lib/index.js @@ -213,11 +213,17 @@ internals.handler = function (route, handlerOptions) { return settings.onResponse.call(bind, null, res, request, h, settings, ttl); } - return h.response(res) + const response = h.response(res) .ttl(ttl) .code(res.statusCode) .passThrough(!!settings.passThrough); + if (!settings.passThrough && res.statusCode === 405 && 'allow' in res.headers) { + response.header('allow', res.headers.allow); + } + + return response; + }; }; diff --git a/test/index.js b/test/index.js index 1f78914..e5d02fc 100755 --- a/test/index.js +++ b/test/index.js @@ -2215,4 +2215,88 @@ describe('h2o2', () => { await server.stop(); await upstream.stop(); }); + + it('propagates the allow header in case of 405 (with passthrough)', async () => { + + const upstream = Hapi.server(); + upstream.route({ + method: 'POST', + path: '/item', + handler(request, h) { + + throw Boom.methodNotAllowed('Not allowed', {}, ['GET']); + } + }); + + await upstream.start(); + + const server = Hapi.server(); + await server.register(H2o2); + + server.route({ method: 'POST', path: '/item', handler: { proxy: { host: upstream.info.address, port: upstream.info.port, passThrough: true } } }); + await server.start(); + + const res = await server.inject({ method: 'POST', url: '/item' }); + expect(res.statusCode).to.equal(405); + expect(res.headers.allow).to.equal('GET'); + + await server.stop(); + await upstream.stop(); + }); + + it('propagates the allow header in case of 405 (without passthrough)', async () => { + + const upstream = Hapi.server(); + upstream.route({ + method: 'POST', + path: '/item', + handler(request, h) { + + throw Boom.methodNotAllowed('Not allowed', {}, ['GET']); + } + }); + + await upstream.start(); + + const server = Hapi.server(); + await server.register(H2o2); + + server.route({ method: 'POST', path: '/item', handler: { proxy: { host: upstream.info.address, port: upstream.info.port } } }); + await server.start(); + + const res = await server.inject({ method: 'POST', url: '/item' }); + expect(res.statusCode).to.equal(405); + expect(res.headers.allow).to.equal('GET'); + + await server.stop(); + await upstream.stop(); + }); + + it('does not propagate a missing allow header in case of malformed 405', async () => { + + const upstream = Hapi.server(); + upstream.route({ + method: 'POST', + path: '/item', + handler(request, h) { + + throw Boom.methodNotAllowed('Not allowed'); + } + }); + + await upstream.start(); + + const server = Hapi.server(); + await server.register(H2o2); + + server.route({ method: 'POST', path: '/item', handler: { proxy: { host: upstream.info.address, port: upstream.info.port } } }); + await server.start(); + + const res = await server.inject({ method: 'POST', url: '/item' }); + expect(res.statusCode).to.equal(405); + expect(res.headers.allow).to.not.exist(); + + await server.stop(); + await upstream.stop(); + }); });