diff --git a/lib/server.js b/lib/server.js index ff03553eb..8b7823e43 100644 --- a/lib/server.js +++ b/lib/server.js @@ -82,6 +82,8 @@ class Server extends KarmaEventEmitter { filesPromise: ['factory', createFilesPromise], socketServer: ['factory', createSocketIoServer], executor: ['factory', Executor.factory], + // TODO: Deprecated. Remove in the next major + customFileHandlers: ['value', []], reporter: ['factory', reporter.createReporters], capturedBrowsers: ['factory', BrowserCollection.factory], args: ['value', {}], diff --git a/lib/web-server.js b/lib/web-server.js index 379818435..394066b7b 100644 --- a/lib/web-server.js +++ b/lib/web-server.js @@ -16,6 +16,25 @@ const proxyMiddleware = require('./middleware/proxy') const log = require('./logger').create('web-server') +function createCustomHandler (customFileHandlers, config) { + let warningDone = false + + return function (request, response, next) { + const handler = customFileHandlers.find((handler) => handler.urlRegex.test(request.url)) + + if (customFileHandlers.length > 0 && !warningDone) { + warningDone = true + log.warn('The `customFileHandlers` is deprecated and will be removed in Karma 7. Please upgrade plugins relying on this provider.') + } + + return handler + ? handler.handler(request, response, 'fake/static', 'fake/adapter', config.basePath, 'fake/root') + : next() + } +} + +createCustomHandler.$inject = ['customFileHandlers', 'config'] + function createFilesPromise (emitter, fileList) { // Set an empty list of files to avoid race issues with // file_list_modified not having been emitted yet @@ -58,6 +77,8 @@ function createWebServer (injector, config) { handler.use(injector.invoke(sourceFilesMiddleware.create)) // TODO(vojta): extract the proxy into a plugin handler.use(proxyMiddlewareInstance) + // TODO: Deprecated. Remove in the next major + handler.use(injector.invoke(createCustomHandler)) if (config.middleware) { config.middleware.forEach((middleware) => handler.use(injector.get('middleware:' + middleware))) diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index 8517f172e..5d9f4f18e 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -31,7 +31,7 @@ describe('web-server', () => { // NOTE(vojta): only loading once, to speed things up // this relies on the fact that none of these tests mutate fs const m = mocks.loadFile(path.join(__dirname, '/../../lib/web-server.js'), _mocks, _globals) - server = emitter = null + let customFileHandlers = server = emitter = null let beforeMiddlewareActive = false let middlewareActive = false const servedFiles = (files) => { @@ -40,6 +40,7 @@ describe('web-server', () => { describe('request', () => { beforeEach(() => { + customFileHandlers = [] emitter = new EventEmitter() const config = { basePath: '/base/path', @@ -56,6 +57,7 @@ describe('web-server', () => { const injector = new di.Injector([{ config: ['value', config], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -180,6 +182,23 @@ describe('web-server', () => { }) }) + it('should load custom handlers', () => { + servedFiles(new Set()) + + // TODO(vojta): change this, only keeping because karma-dart is relying on it + customFileHandlers.push({ + urlRegex: /\/some\/weird/, + handler (request, response, staticFolder, adapterFolder, baseFolder, urlRoot) { + response.writeHead(222) + response.end('CONTENT') + } + }) + + return request(server) + .get('/some/weird/url') + .expect(222, 'CONTENT') + }) + it('should serve 404 for non-existing files', () => { servedFiles(new Set()) @@ -196,6 +215,7 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } + customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ @@ -206,6 +226,7 @@ describe('web-server', () => { httpsServerOptions: credentials, client: { useIframe: true, useSingleWindow: false } }], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -244,10 +265,12 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } + customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ config: ['value', { basePath: '/base/path', urlRoot: '/', httpModule: http2, protocol: 'https:', httpsServerOptions: credentials }], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise],