Skip to content

Commit

Permalink
feat(server): add support for http proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoffer Åström committed Jan 29, 2019
1 parent 427288b commit c730e4f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 2 deletions.
4 changes: 4 additions & 0 deletions commands/protractor/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ if (argv.seleniumServerJar) {
argv.seleniumServerJar = jar;
}

if (argv.glob.length) {
argv.specs = argv.glob.map(p => path.resolve(p));
}

module.exports = {
config: argv,
};
2 changes: 1 addition & 1 deletion commands/protractor/src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = {
description: 'Glob pattern',
type: 'array',
default: TEST_GLOB,
alias: ['glob', 'specs'],
alias: ['glob'],
},
coverage: {
description: 'Generate coverage',
Expand Down
1 change: 1 addition & 0 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dependencies": {
"@after-work.js/transform-middleware": "5.1.1",
"@after-work.js/utils": "5.1.1",
"http-proxy-middleware": "0.19.1",
"import-cwd": "2.1.0",
"express": "4.16.4",
"serve-favicon": "2.5.0",
Expand Down
6 changes: 5 additions & 1 deletion packages/server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ const path = require('path');
const express = require('express');
const favicon = require('serve-favicon');
const transformFiles = require('@after-work.js/transform-middleware');
const applyProxies = require('./proxies');

module.exports = function createServer(options) {
const { middleware = () => {}, ...argv } = options;
const app = express();
const websocketProxies = applyProxies(app, options.proxy);
app.use(favicon(path.resolve(__dirname, '../aw.png')));
app.use(transformFiles(argv));
app.use('/', express.static(process.cwd()));
middleware(app, express);
return app.listen(argv.http.port, '0.0.0.0', (err) => {
const server = app.listen(argv.http.port, '0.0.0.0', (err) => {
if (err) {
throw err;
}
// eslint-disable-next-line no-console
console.error(`Listening on http://0.0.0.0:${argv.http.port}`);
});
websocketProxies.forEach(wsProxy => server.on('upgrade', wsProxy.upgrade));
return server;
};
81 changes: 81 additions & 0 deletions packages/server/src/proxies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const httpProxyMiddleware = require('http-proxy-middleware');

const getProxyMiddleware = (proxyConfig) => {
if (typeof proxyConfig.logLevel === 'undefined') {
proxyConfig.logLevel = 'error';
}
const context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return httpProxyMiddleware(context, proxyConfig);
}
return null;
};

const normalize = options => Object.keys(options).map((context) => {
let proxyOptions;
const correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
if (typeof options.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: options.proxy[context],
};
} else {
proxyOptions = Object.assign({}, options.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions;
});

const applyProxies = (app, options = []) => {
const websocketProxies = [];
const proxy = !Array.isArray(options) ? normalize(options) : options;
proxy.forEach((proxyConfigOrCallback) => {
let proxyConfig;
let proxyMiddleware;

if (typeof proxyConfigOrCallback === 'function') {
proxyConfig = proxyConfigOrCallback();
} else {
proxyConfig = proxyConfigOrCallback;
}

proxyMiddleware = getProxyMiddleware(proxyConfig);

if (proxyConfig.ws) {
websocketProxies.push(proxyMiddleware);
}

app.use((req, res, next) => { // eslint-disable-line
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();

if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}

const bypass = typeof proxyConfig.bypass === 'function';

const bypassUrl = (bypass && proxyConfig.bypass(req, res, proxyConfig)) || false;

if (bypassUrl) {
req.url = bypassUrl;

next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
});
});
return websocketProxies;
};

module.exports = applyProxies;

0 comments on commit c730e4f

Please sign in to comment.