Use ws directly to handle new exec ws route

This commit is contained in:
Girish Ramakrishnan
2017-08-18 17:56:01 -07:00
parent e3040b334d
commit 537fbff4aa
5 changed files with 91 additions and 84 deletions

View File

@@ -19,7 +19,8 @@ var assert = require('assert'),
middleware = require('./middleware'),
passport = require('passport'),
path = require('path'),
routes = require('./routes/index.js');
routes = require('./routes/index.js'),
ws = require('ws');
var gHttpServer = null;
var gSysadminHttpServer = null;
@@ -28,8 +29,7 @@ function initializeExpressSync() {
var app = express();
var httpServer = http.createServer(app);
// enabled websocket handling
require('express-ws')(app, httpServer);
const wsServer = new ws.Server({ noServer: true }); // in noServer mode, we have to handle 'upgrade' and call handleUpgrade
var QUERY_LIMIT = '1mb', // max size for json and urlencoded queries (see also client_max_body_size in nginx)
FIELD_LIMIT = 2 * 1024 * 1024; // max fields that can appear in multipart
@@ -192,7 +192,8 @@ function initializeExpressSync() {
router.get ('/api/v1/apps/:id/logstream', appsScope, routes.user.requireAdmin, routes.apps.getLogStream);
router.get ('/api/v1/apps/:id/logs', appsScope, routes.user.requireAdmin, routes.apps.getLogs);
router.get ('/api/v1/apps/:id/exec', routes.developer.enabled, appsScope, routes.user.requireAdmin, routes.apps.exec);
router.ws ('/api/v1/apps/:id/execws', routes.oauth2.websocketAuth, routes.apps.execWebSocket);
// websocket cannot do bearer authentication
router.get ('/api/v1/apps/:id/execws', routes.oauth2.websocketAuth.bind(null, [ clients.SCOPE_APPS ]), routes.user.requireAdmin, routes.apps.execWebSocket);
router.post('/api/v1/apps/:id/clone', appsScope, routes.user.requireAdmin, routes.apps.cloneApp);
// settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above)
@@ -238,13 +239,15 @@ function initializeExpressSync() {
// upgrade handler
httpServer.on('upgrade', function (req, socket, head) {
// create a node response object for express
var res = new http.ServerResponse({});
res.assignSocket(socket);
if (req.headers.upgrade === 'websocket') {
// websocket connections should never time out
req.clearTimeout();
res.handleUpgrade = function (callback) {
wsServer.handleUpgrade(req, socket, head, callback);
};
} else {
// create a node response object for express
var res = new http.ServerResponse({});
res.assignSocket(socket);
res.sendUpgradeHandshake = function () { // could extend express.response as well
console.log('----- now send the upgrade handshake')
socket.write('HTTP/1.1 101 TCP Handshake\r\n' +
@@ -252,11 +255,11 @@ function initializeExpressSync() {
'Connection: Upgrade\r\n' +
'\r\n');
};
// route through express middleware. if we provide no callback, express will provide a 'finalhandler'
// TODO: it's not clear if socket needs to be destroyed
app(req, res);
}
// route through express middleware. if we provide no callback, express will provide a 'finalhandler'
// TODO: it's not clear if socket needs to be destroyed
app(req, res);
});
return httpServer;