diff options
Diffstat (limited to 'vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware')
6 files changed, 563 insertions, 0 deletions
diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/common.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/common.js new file mode 100644 index 00000000..2e37475d --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/common.js @@ -0,0 +1,88 @@ +/** + * This module contains some common helpers shared between middlewares + */ + +var mime = require('mime') +var log = require('../logger').create('web-server') + +var PromiseContainer = function () { + var promise + + this.then = function (success, error) { + return promise.then(success, error) + } + + this.set = function (newPromise) { + promise = newPromise + } +} + +var serve404 = function (response, path) { + log.warn('404: ' + path) + response.writeHead(404) + return response.end('NOT FOUND') +} + +var createServeFile = function (fs, directory) { + var cache = Object.create(null) + + return function (filepath, response, transform, content) { + var responseData + + if (directory) { + filepath = directory + filepath + } + + if (!content && cache[filepath]) { + content = cache[filepath] + } + + // serve from cache + if (content) { + response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain')) + + // call custom transform fn to transform the data + responseData = transform && transform(content) || content + + response.writeHead(200) + + log.debug('serving (cached): ' + filepath) + return response.end(responseData) + } + + return fs.readFile(filepath, function (error, data) { + if (error) { + return serve404(response, filepath) + } + + cache[filepath] = data.toString() + + response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain')) + + // call custom transform fn to transform the data + responseData = transform && transform(data.toString()) || data + + response.writeHead(200) + + log.debug('serving: ' + filepath) + return response.end(responseData) + }) + } +} + +var setNoCacheHeaders = function (response) { + response.setHeader('Cache-Control', 'no-cache') + response.setHeader('Pragma', 'no-cache') + response.setHeader('Expires', (new Date(0)).toString()) +} + +var setHeavyCacheHeaders = function (response) { + response.setHeader('Cache-Control', ['public', 'max-age=31536000']) +} + +// PUBLIC API +exports.PromiseContainer = PromiseContainer +exports.createServeFile = createServeFile +exports.setNoCacheHeaders = setNoCacheHeaders +exports.setHeavyCacheHeaders = setHeavyCacheHeaders +exports.serve404 = serve404 diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/karma.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/karma.js new file mode 100644 index 00000000..a9186fa6 --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/karma.js @@ -0,0 +1,176 @@ +/** + * Karma middleware is responsible for serving: + * - client.html (the entrypoint for capturing a browser) + * - debug.html + * - context.html (the execution context, loaded within an iframe) + * - karma.js + * + * The main part is generating context.html, as it contains: + * - generating mappings + * - including <script> and <link> tags + * - setting propert caching headers + */ + +var path = require('path') +var util = require('util') +var url = require('url') + +var urlparse = function (urlStr) { + var urlObj = url.parse(urlStr, true) + urlObj.query = urlObj.query || {} + return urlObj +} + +var common = require('./common') + +var VERSION = require('../constants').VERSION +var SCRIPT_TAG = '<script type="%s" src="%s"></script>' +var LINK_TAG_CSS = '<link type="text/css" href="%s" rel="stylesheet">' +var LINK_TAG_HTML = '<link href="%s" rel="import">' +var SCRIPT_TYPE = { + '.js': 'text/javascript', + '.dart': 'application/dart' +} + +var filePathToUrlPath = function (filePath, basePath) { + if (filePath.indexOf(basePath) === 0) { + return '/base' + filePath.substr(basePath.length) + } + + return '/absolute' + filePath +} + +var getXUACompatibleMetaElement = function (url) { + var tag = '' + var urlObj = urlparse(url) + if (urlObj.query['x-ua-compatible']) { + tag = '\n<meta http-equiv="X-UA-Compatible" content="' + + urlObj.query['x-ua-compatible'] + '"/>' + } + return tag +} + +var getXUACompatibleUrl = function (url) { + var value = '' + var urlObj = urlparse(url) + if (urlObj.query['x-ua-compatible']) { + value = '?x-ua-compatible=' + encodeURIComponent(urlObj.query['x-ua-compatible']) + } + return value +} + +var createKarmaMiddleware = function (filesPromise, serveStaticFile, + /* config.basePath */ basePath, /* config.urlRoot */ urlRoot, /* config.client */ client) { + return function (request, response, next) { + var requestUrl = request.normalizedUrl.replace(/\?.*/, '') + + // redirect /__karma__ to /__karma__ (trailing slash) + if (requestUrl === urlRoot.substr(0, urlRoot.length - 1)) { + response.setHeader('Location', urlRoot) + response.writeHead(301) + return response.end('MOVED PERMANENTLY') + } + + // ignore urls outside urlRoot + if (requestUrl.indexOf(urlRoot) !== 0) { + return next() + } + + // remove urlRoot prefix + requestUrl = requestUrl.substr(urlRoot.length - 1) + + // serve client.html + if (requestUrl === '/') { + return serveStaticFile('/client.html', response, function (data) { + return data + .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) + .replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url)) + }) + } + + // serve karma.js + if (requestUrl === '/karma.js') { + return serveStaticFile(requestUrl, response, function (data) { + return data.replace('%KARMA_URL_ROOT%', urlRoot) + .replace('%KARMA_VERSION%', VERSION) + }) + } + + // serve the favicon + if (requestUrl === '/favicon.ico') { + return serveStaticFile(requestUrl, response) + } + + // serve context.html - execution context within the iframe + // or debug.html - execution context without channel to the server + if (requestUrl === '/context.html' || requestUrl === '/debug.html') { + return filesPromise.then(function (files) { + serveStaticFile(requestUrl, response, function (data) { + common.setNoCacheHeaders(response) + + var scriptTags = files.included.map(function (file) { + var filePath = file.path + var fileExt = path.extname(filePath) + + if (!file.isUrl) { + // TODO(vojta): serve these files from within urlRoot as well + filePath = filePathToUrlPath(filePath, basePath) + + if (requestUrl === '/context.html') { + filePath += '?' + file.sha + } + } + + if (fileExt === '.css') { + return util.format(LINK_TAG_CSS, filePath) + } + + if (fileExt === '.html') { + return util.format(LINK_TAG_HTML, filePath) + } + + return util.format(SCRIPT_TAG, SCRIPT_TYPE[fileExt] || 'text/javascript', filePath) + }) + + // TODO(vojta): don't compute if it's not in the template + var mappings = files.served.map(function (file) { + // Windows paths contain backslashes and generate bad IDs if not escaped + var filePath = filePathToUrlPath(file.path, basePath).replace(/\\/g, '\\\\') + + return util.format(" '%s': '%s'", filePath, file.sha) + }) + + var clientConfig = '' + + if (requestUrl === '/debug.html') { + clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n' + } + + mappings = 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n' + + return data + .replace('%SCRIPTS%', scriptTags.join('\n')) + .replace('%CLIENT_CONFIG%', clientConfig) + .replace('%MAPPINGS%', mappings) + .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) + }) + }, function (errorFiles) { + serveStaticFile(requestUrl, response, function (data) { + common.setNoCacheHeaders(response) + return data.replace('%SCRIPTS%', '').replace('%CLIENT_CONFIG%', '').replace('%MAPPINGS%', + 'window.__karma__.error("TEST RUN WAS CANCELLED because ' + + (errorFiles.length > 1 ? 'these files contain' : 'this file contains') + + ' some errors:\\n ' + errorFiles.join('\\n ') + '");') + }) + }) + } + + return next() + } +} + +createKarmaMiddleware.$inject = ['filesPromise', 'serveStaticFile', + 'config.basePath', 'config.urlRoot', 'config.client'] + +// PUBLIC API +exports.create = createKarmaMiddleware diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/proxy.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/proxy.js new file mode 100644 index 00000000..a3e9f001 --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/proxy.js @@ -0,0 +1,130 @@ +var url = require('url') +var httpProxy = require('http-proxy') + +var log = require('../logger').create('proxy') + +var parseProxyConfig = function (proxies, config) { + var proxyConfig = {} + var endsWithSlash = function (str) { + return str.substr(-1) === '/' + } + + if (!proxies) { + return proxyConfig + } + + Object.keys(proxies).forEach(function (proxyPath) { + var proxyUrl = proxies[proxyPath] + var proxyDetails = url.parse(proxyUrl) + var pathname = proxyDetails.pathname + + // normalize the proxies config + // should we move this to lib/config.js ? + if (endsWithSlash(proxyPath) && !endsWithSlash(proxyUrl)) { + log.warn('proxy "%s" normalized to "%s"', proxyUrl, proxyUrl + '/') + proxyUrl += '/' + pathname += '/' + } + + if (!endsWithSlash(proxyPath) && endsWithSlash(proxyUrl)) { + log.warn('proxy "%s" normalized to "%s"', proxyPath, proxyPath + '/') + proxyPath += '/' + } + + if (pathname === '/' && !endsWithSlash(proxyUrl)) { + pathname = '' + } + + proxyConfig[proxyPath] = { + host: proxyDetails.hostname, + port: proxyDetails.port, + baseProxyUrl: pathname, + https: proxyDetails.protocol === 'https:' + } + + if (!proxyConfig[proxyPath].port) { + if (!proxyConfig[proxyPath].host) { + proxyConfig[proxyPath].host = config.hostname + proxyConfig[proxyPath].port = config.port + } else { + proxyConfig[proxyPath].port = proxyConfig[proxyPath].https ? '443' : '80' + } + } + }) + + return proxyConfig +} + +/** + * Returns a handler which understands the proxies and its redirects, along with the proxy to use + * @param proxy A http-proxy.RoutingProxy object with the proxyRequest method + * @param proxies a map of routes to proxy url + * @return {Function} handler function + */ +var createProxyHandler = function (proxy, proxyConfig, proxyValidateSSL, urlRoot, config) { + var proxies = parseProxyConfig(proxyConfig, config) + var proxiesList = Object.keys(proxies).sort().reverse() + + if (!proxiesList.length) { + var nullProxy = function createNullProxy (request, response, next) { + return next() + } + nullProxy.upgrade = function upgradeNullProxy () {} + return nullProxy + } + + proxy.on('proxyError', function (err, req) { + if (err.code === 'ECONNRESET' && req.socket.destroyed) { + log.debug('failed to proxy %s (browser hung up the socket)', req.url) + } else { + log.warn('failed to proxy %s (%s)', req.url, err.message) + } + }) + + var middleware = function createProxy (request, response, next) { + for (var i = 0; i < proxiesList.length; i++) { + if (request.url.indexOf(proxiesList[i]) === 0) { + var proxiedUrl = proxies[proxiesList[i]] + + log.debug('proxying request - %s to %s:%s', request.url, proxiedUrl.host, proxiedUrl.port) + request.url = request.url.replace(proxiesList[i], proxiedUrl.baseProxyUrl) + proxy.proxyRequest(request, response, { + host: proxiedUrl.host, + port: proxiedUrl.port, + target: {https: proxiedUrl.https, rejectUnauthorized: proxyValidateSSL} + }) + return + } + } + + return next() + } + + middleware.upgrade = function upgradeProxy (request, socket, head) { + // special-case karma's route to avoid upgrading it + if (request.url.indexOf(urlRoot) === 0) { + log.debug('NOT upgrading proxyWebSocketRequest %s', request.url) + return + } + for (var i = 0; i < proxiesList.length; i++) { + if (request.url.indexOf(proxiesList[i]) === 0) { + var proxiedUrl = proxies[proxiesList[i]] + log.debug('upgrade proxyWebSocketRequest %s to %s:%s', + request.url, proxiedUrl.host, proxiedUrl.port) + proxy.proxyWebSocketRequest(request, socket, head, + {host: proxiedUrl.host, port: proxiedUrl.port}) + } + } + } + + return middleware +} + +var createProxyHandlerFactory = function (/* config */ config, /* config.proxies */ proxies, + /* config.proxyValidateSSL */ validateSSL) { + return createProxyHandler(new httpProxy.RoutingProxy({changeOrigin: true}), + proxies, validateSSL, config.urlRoot, config) +} +createProxyHandlerFactory.$inject = ['config', 'config.proxies', 'config.proxyValidateSSL'] + +exports.create = createProxyHandlerFactory diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/runner.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/runner.js new file mode 100644 index 00000000..36c8055b --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/runner.js @@ -0,0 +1,92 @@ +/** + * Runner middleware is reponsible for communication with `karma run`. + * + * It basically triggers a test run and streams stdout back. + */ + +var path = require('path') +var helper = require('../helper') +var log = require('../logger').create() +var constant = require('../constants') +var json = require('connect').json() + +// TODO(vojta): disable when single-run mode +var createRunnerMiddleware = function (emitter, fileList, capturedBrowsers, reporter, executor, + /* config.hostname */ hostname, /* config.port */ port, /* config.urlRoot */ urlRoot, config) { + return function (request, response, next) { + if (request.url !== '/__run__' && request.url !== urlRoot + 'run') { + return next() + } + + log.debug('Execution (fired by runner)') + response.writeHead(200) + + if (!capturedBrowsers.length) { + var url = 'http://' + hostname + ':' + port + urlRoot + + return response.end('No captured browser, open ' + url + '\n') + } + + json(request, response, function () { + if (!capturedBrowsers.areAllReady([])) { + response.write('Waiting for previous execution...\n') + } + + emitter.once('run_start', function () { + var responseWrite = response.write.bind(response) + + reporter.addAdapter(responseWrite) + + // clean up, close runner response + emitter.once('run_complete', function (browsers, results) { + reporter.removeAdapter(responseWrite) + response.end(constant.EXIT_CODE + results.exitCode) + }) + }) + + var data = request.body + log.debug('Setting client.args to ', data.args) + config.client.args = data.args + + var fullRefresh = true + + if (helper.isArray(data.changedFiles)) { + data.changedFiles.forEach(function (filepath) { + fileList.changeFile(path.resolve(config.basePath, filepath)) + fullRefresh = false + }) + } + + if (helper.isArray(data.addedFiles)) { + data.addedFiles.forEach(function (filepath) { + fileList.addFile(path.resolve(config.basePath, filepath)) + fullRefresh = false + }) + } + + if (helper.isArray(data.removedFiles)) { + data.removedFiles.forEach(function (filepath) { + fileList.removeFile(path.resolve(config.basePath, filepath)) + fullRefresh = false + }) + } + + if (fullRefresh && data.refresh !== false) { + log.debug('Refreshing all the files / patterns') + fileList.refresh() + + if (!config.autoWatch) { + executor.schedule() + } + } else { + executor.schedule() + } + }) + } +} + +createRunnerMiddleware.$inject = ['emitter', 'fileList', 'capturedBrowsers', 'reporter', 'executor', + 'config.hostname', 'config.port', 'config.urlRoot', 'config'] + +// PUBLIC API +exports.create = createRunnerMiddleware diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/source_files.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/source_files.js new file mode 100644 index 00000000..95d4c032 --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/source_files.js @@ -0,0 +1,59 @@ +/** + * Source Files middleware is responsible for serving all the source files under the test. + */ + +var querystring = require('querystring') +var common = require('./common') +var pause = require('connect').utils.pause + +var findByPath = function (files, path) { + for (var i = 0; i < files.length; i++) { + if (files[i].path === path) { + return files[i] + } + } + + return null +} + +var createSourceFilesMiddleware = function (filesPromise, serveFile, + /* config.basePath */ basePath) { + return function (request, response, next) { + // TODO(vojta): serve files under urlRoot (also update the formatError) + var requestedFilePath = querystring.unescape(request.url) + .replace(/\?.*$/, '') + .replace(/^\/absolute/, '') + .replace(/^\/base/, basePath) + + // Need to pause the request because of proxying, see: + // https://groups.google.com/forum/#!topic/q-continuum/xr8znxc_K5E/discussion + // TODO(vojta): remove once we don't care about Node 0.8 + var pausedRequest = pause(request) + + return filesPromise.then(function (files) { + // TODO(vojta): change served to be a map rather then an array + var file = findByPath(files.served, requestedFilePath) + + if (file) { + serveFile(file.contentPath || file.path, response, function () { + if (/\?\w+/.test(request.url)) { + // files with timestamps - cache one year, rely on timestamps + common.setHeavyCacheHeaders(response) + } else { + // without timestamps - no cache (debug) + common.setNoCacheHeaders(response) + } + }, file.content) + } else { + next() + } + + pausedRequest.resume() + }) + } +} + +createSourceFilesMiddleware.$inject = ['filesPromise', 'serveFile', 'config.basePath'] + +// PUBLIC API +exports.create = createSourceFilesMiddleware diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/strip_host.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/strip_host.js new file mode 100644 index 00000000..6851b779 --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/middleware/strip_host.js @@ -0,0 +1,18 @@ +/** + * Strip host middleware is responsible for stripping hostname from request path + * This to handle requests that uses (normally over proxies) an absolutURI as request path + */ + +var createStripHostMiddleware = function () { + return function (request, response, next) { + function stripHostFromUrl (url) { + return url.replace(/^http[s]?:\/\/([a-z\-\.\:\d]+)\//, '/') + } + + request.normalizedUrl = stripHostFromUrl(request.url) || request.url + next() + } +} + +// PUBLIC API +exports.create = createStripHostMiddleware |