diff --git a/main.js b/main.js index 10a98918..08f2fc5e 100644 --- a/main.js +++ b/main.js @@ -41,6 +41,7 @@ const teapot = fs.readFileSync( path.join(__dirname, 'src/assets/teapot.ascii'), 'utf8' ); +const generateViaMiddleware = require('./src/middleware/via'); /** * @param {AppOptions} options @@ -98,6 +99,9 @@ const getAppContainer = (options) => { app.set('x-powered-by', false); app.use(security); + // Add the application system code to the Via HTTP header + app.use(generateViaMiddleware(meta.systemCode)); + // utility middleware app.use(vary); diff --git a/src/middleware/via.js b/src/middleware/via.js new file mode 100644 index 00000000..268d046d --- /dev/null +++ b/src/middleware/via.js @@ -0,0 +1,16 @@ +/** + * @typedef {import("../../typings/n-express").Callback} Callback + */ + +/** + * @param {string} systemCode + * @returns {Callback} + */ +module.exports = function generateViaMiddleware (systemCode) { + return (request, response, next) => { + const requestVia = request.get('via'); + const appViaEntry = `${request.httpVersion} ${systemCode}`; + response.set('via', requestVia ? `${requestVia}, ${appViaEntry}` : appViaEntry); + next(); + }; +}; diff --git a/test/middleware/via.test.js b/test/middleware/via.test.js new file mode 100644 index 00000000..27f50b8f --- /dev/null +++ b/test/middleware/via.test.js @@ -0,0 +1,43 @@ +const generateViaMiddleware = require('../../src/middleware/via'); +const sinon = require('sinon'); +const sinonChai = require('sinon-chai'); +const chai = require('chai'); +const expect = chai.expect; +chai.use(sinonChai); + +describe('via middleware', function () { + let middleware; + let request; + let response; + let next; + + beforeEach(() => { + request = { + get: sinon.stub().withArgs('via').returns(undefined), + httpVersion: 'mock-http-version' + }; + response = { + set: sinon.spy() + }; + next = sinon.spy(); + middleware = generateViaMiddleware('mock-system'); + }); + + describe('when no request Via header is present', () => { + it('sends a response Via header set to the application system code', () => { + middleware(request, response, next); + expect(response.set).calledWithExactly('via', 'mock-http-version mock-system'); + expect(next).calledWithExactly(); + }); + }); + + describe('when a request Via header is present', () => { + it('sends a response Via header appending the application system code', () => { + request.get.withArgs('via').returns('mock-request-via'); + middleware(request, response, next); + expect(response.set).calledWithExactly('via', 'mock-request-via, mock-http-version mock-system'); + expect(next).calledWithExactly(); + }); + }); + +});