diff --git a/lib/filter-rules-loading.js b/lib/filter-rules-loading.js new file mode 100644 index 000000000..4dfcefe81 --- /dev/null +++ b/lib/filter-rules-loading.js @@ -0,0 +1,16 @@ +const path = require('path'); +const yaml = require('js-yaml'); +const fs = require('fs'); + +module.exports = (acceptFilename = '', folderLocation = '') => { + let filters = {}; + if (acceptFilename) { + const acceptLocation = path.resolve( + folderLocation ? folderLocation : process.cwd(), + acceptFilename, + ); + + filters = yaml.safeLoad(fs.readFileSync(acceptLocation, 'utf8')); + } + return filters; +}; diff --git a/lib/index.js b/lib/index.js index 1c253fa94..aa2d192d0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,9 +4,8 @@ require('predefine').merge = require('lodash.merge'); require('clarify'); // clean the stacktraces -const path = require('path'); -const yaml = require('js-yaml'); -const fs = require('fs'); + +const filterRulesLoader = require('./filter-rules-loading'); const logger = require('./log'); const app = (module.exports = { @@ -40,12 +39,7 @@ function main({ port, client, config = {} } = {}) { logger.debug({ accept: localConfig.accept }, 'loading rules'); - let filters = {}; - if (localConfig.accept) { - const acceptLocation = path.resolve(process.cwd(), localConfig.accept); - - filters = yaml.safeLoad(fs.readFileSync(acceptLocation, 'utf8')); - } + let filters = filterRulesLoader(localConfig.accept); // if the localConfig has the broker server, then we must assume it's a client return app[method]({ config: localConfig, port, filters }); diff --git a/lib/relay.js b/lib/relay.js index 089fbd134..39e9d50b2 100644 --- a/lib/relay.js +++ b/lib/relay.js @@ -347,7 +347,7 @@ function forwardWebSocketRequest(filterRules, config, io) { const body = responseData.body; delete responseData.body; logger.trace( - {...logContext, responseData, body}, + { ...logContext, responseData, body }, "posting internal response back to Broker Server as it's expecting streaming response", ); const buffer = initStream( @@ -362,17 +362,28 @@ function forwardWebSocketRequest(filterRules, config, io) { } else { if (streamingID) { if (responseData instanceof request.Request) { - legacyStreaming(logContext, responseData, config, io, streamingID); + legacyStreaming( + logContext, + responseData, + config, + io, + streamingID, + ); } else { io.send('chunk', streamingID, '', false, { status: responseData.status, headers: responseData.headers, }); - io.send('chunk', streamingID, JSON.stringify(responseData.body), true); + io.send( + 'chunk', + streamingID, + JSON.stringify(responseData.body), + true, + ); } } else { logger.trace( - {...logContext, responseData}, + { ...logContext, responseData }, 'sending fixed response over WebSocket connection', ); realEmit(responseData); diff --git a/test/functional/client-server.test.js b/test/functional/client-server.test.js index 832377039..93fec4a31 100644 --- a/test/functional/client-server.test.js +++ b/test/functional/client-server.test.js @@ -155,22 +155,28 @@ test('proxy requests originating from behind the broker client', (t) => { }); // the filtering happens in the broker server - t.test('block request for valid URL which is not allowed on server', (t) => { - const url = `http://localhost:${clientPort}/server-side-blocked`; - request({ url, method: 'get' }, (err, res) => { - t.equal(res.statusCode, 401, '401 statusCode'); - t.end(); - }); - }); + t.test( + 'block request for valid URL which is not allowed on server', + (t) => { + const url = `http://localhost:${clientPort}/server-side-blocked`; + request({ url, method: 'get' }, (err, res) => { + t.equal(res.statusCode, 401, '401 statusCode'); + t.end(); + }); + }, + ); // the filtering happens in the broker server - this indicates a very badly misconfigured client - t.test('block request for valid URL which is not allowed on server with streaming response', (t) => { - const url = `http://localhost:${clientPort}/server-side-blocked-streaming`; - request({ url, method: 'get' }, (err, res) => { - t.equal(res.statusCode, 401, '401 statusCode'); - t.end(); - }); - }); + t.test( + 'block request for valid URL which is not allowed on server with streaming response', + (t) => { + const url = `http://localhost:${clientPort}/server-side-blocked-streaming`; + request({ url, method: 'get' }, (err, res) => { + t.equal(res.statusCode, 401, '401 statusCode'); + t.end(); + }); + }, + ); t.test('allow request for valid url with valid accept header', (t) => { const url = `http://localhost:${clientPort}/echo-param-protected/xyz`; diff --git a/test/unit/runtime-rules-hotloading.test.ts b/test/unit/runtime-rules-hotloading.test.ts new file mode 100644 index 000000000..b3abf2154 --- /dev/null +++ b/test/unit/runtime-rules-hotloading.test.ts @@ -0,0 +1,22 @@ +import { readFileSync } from 'fs'; +import * as path from 'path'; +import * as loadFilterRules from '../../lib/filter-rules-loading'; + +function loadFixture(name: string) { + const fixturePath = path.join(__dirname, '..', 'fixtures', name); + const fixture = readFileSync(fixturePath, { encoding: 'utf-8' }); + + return fixture; +} + +describe('filter Rules Loading', () => { + it('Loads normal accept file', () => { + const rules = JSON.parse(loadFixture(path.join('accept', 'ghe.json'))); + const loadedRules = loadFilterRules( + 'ghe.json', + path.join(__dirname, '..', 'fixtures/accept'), + ); + + expect(loadedRules).toEqual(rules); + }); +});