web-server.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. 'use strict'
  2. const fs = require('graceful-fs')
  3. const http = require('http')
  4. const https = require('https')
  5. const path = require('path')
  6. const connect = require('connect')
  7. const mimeType = require('mime')
  8. const common = require('./middleware/common')
  9. const runnerMiddleware = require('./middleware/runner')
  10. const stopperMiddleware = require('./middleware/stopper')
  11. const karmaMiddleware = require('./middleware/karma')
  12. const sourceFilesMiddleware = require('./middleware/source_files')
  13. const proxyMiddleware = require('./middleware/proxy')
  14. const log = require('./logger').create('web-server')
  15. function createCustomHandler (customFileHandlers, config) {
  16. let warningDone = false
  17. return function (request, response, next) {
  18. const handler = customFileHandlers.find((handler) => handler.urlRegex.test(request.url))
  19. if (customFileHandlers.length > 0 && !warningDone) {
  20. warningDone = true
  21. log.warn('The `customFileHandlers` is deprecated and will be removed in Karma 7. Please upgrade plugins relying on this provider.')
  22. }
  23. return handler
  24. ? handler.handler(request, response, 'fake/static', 'fake/adapter', config.basePath, 'fake/root')
  25. : next()
  26. }
  27. }
  28. createCustomHandler.$inject = ['customFileHandlers', 'config']
  29. function createFilesPromise (emitter, fileList) {
  30. // Set an empty list of files to avoid race issues with
  31. // file_list_modified not having been emitted yet
  32. let files = fileList.files
  33. emitter.on('file_list_modified', (filesParam) => { files = filesParam })
  34. return {
  35. then (...args) {
  36. return Promise.resolve(files).then(...args)
  37. }
  38. }
  39. }
  40. function createServeStaticFile (config) {
  41. return common.createServeFile(fs, path.normalize(path.join(__dirname, '/../static')), config)
  42. }
  43. createServeStaticFile.$inject = ['config']
  44. function createServeFile (config) {
  45. return common.createServeFile(fs, null, config)
  46. }
  47. createServeFile.$inject = ['config']
  48. function createWebServer (injector, config) {
  49. const { mime = {} } = config
  50. mimeType.define({ ...mime }, true)
  51. const proxyMiddlewareInstance = injector.invoke(proxyMiddleware.create)
  52. log.debug('Instantiating middleware')
  53. const handler = connect()
  54. if (config.beforeMiddleware) {
  55. config.beforeMiddleware.forEach((middleware) => handler.use(injector.get('middleware:' + middleware)))
  56. }
  57. handler.use(injector.invoke(runnerMiddleware.create))
  58. handler.use(injector.invoke(stopperMiddleware.create))
  59. handler.use(injector.invoke(karmaMiddleware.create))
  60. handler.use(injector.invoke(sourceFilesMiddleware.create))
  61. // TODO(vojta): extract the proxy into a plugin
  62. handler.use(proxyMiddlewareInstance)
  63. // TODO: Deprecated. Remove in the next major
  64. handler.use(injector.invoke(createCustomHandler))
  65. if (config.middleware) {
  66. config.middleware.forEach((middleware) => handler.use(injector.get('middleware:' + middleware)))
  67. }
  68. handler.use((request, response) => common.serve404(response, request.url))
  69. let serverClass = http
  70. const serverArguments = [handler]
  71. if (config.protocol === 'https:') {
  72. serverClass = https
  73. serverArguments.unshift(config.httpsServerOptions || {})
  74. }
  75. if (config.httpModule) {
  76. serverClass = config.httpModule
  77. }
  78. const server = serverClass.createServer.apply(null, serverArguments)
  79. server.on('upgrade', function (req, socket, head) {
  80. log.debug(`upgrade ${req.url}`)
  81. proxyMiddlewareInstance.upgrade(req, socket, head)
  82. })
  83. return server
  84. }
  85. createWebServer.$inject = ['injector', 'config']
  86. module.exports = {
  87. createWebServer,
  88. createServeFile,
  89. createServeStaticFile,
  90. createFilesPromise
  91. }