Merge pull request #2296 from ether/new-express

New express
This commit is contained in:
John McLear 2014-11-15 15:36:52 +00:00
commit ab4819fb85
6 changed files with 76 additions and 58 deletions

View file

@ -37,6 +37,7 @@ var _ = require('underscore');
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
var channels = require("channels"); var channels = require("channels");
var stats = require('../stats'); var stats = require('../stats');
var remoteAddress = require("../utils/RemoteAddress").remoteAddress;
/** /**
* A associative array that saves informations about a session * A associative array that saves informations about a session
@ -115,14 +116,16 @@ exports.handleDisconnect = function(client)
//if this connection was already etablished with a handshake, send a disconnect message to the others //if this connection was already etablished with a handshake, send a disconnect message to the others
if(session && session.author) if(session && session.author)
{ {
client.get('remoteAddress', function(er, ip) {
//Anonymize the IP address if IP logging is disabled
if(settings.disableIPlogging) {
ip = 'ANONYMOUS';
}
accessLogger.info('[LEAVE] Pad "'+session.padId+'": Author "'+session.author+'" on client '+client.id+' with IP "'+ip+'" left the pad') // Get the IP address from our persistant object
}) var ip = remoteAddress[client.id];
// Anonymize the IP address if IP logging is disabled
if(settings.disableIPlogging) {
ip = 'ANONYMOUS';
}
accessLogger.info('[LEAVE] Pad "'+session.padId+'": Author "'+session.author+'" on client '+client.id+' with IP "'+ip+'" left the pad')
//get the author color out of the db //get the author color out of the db
authorManager.getAuthorColorId(session.author, function(err, color) authorManager.getAuthorColorId(session.author, function(err, color)
@ -753,7 +756,13 @@ function handleUserChanges(data, cb)
exports.updatePadClients = function(pad, callback) exports.updatePadClients = function(pad, callback)
{ {
//skip this step if noone is on this pad //skip this step if noone is on this pad
var roomClients = socketio.sockets.clients(pad.id); var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
if(roomClients.length==0) if(roomClients.length==0)
return callback(); return callback();
@ -766,10 +775,8 @@ exports.updatePadClients = function(pad, callback)
var revCache = {}; var revCache = {};
//go trough all sessions on this pad //go trough all sessions on this pad
async.forEach(roomClients, function(client, callback) async.forEach(roomClients, function(client, callback){
{
var sid = client.id; var sid = client.id;
//https://github.com/caolan/async#whilst //https://github.com/caolan/async#whilst
//send them all new changesets //send them all new changesets
async.whilst( async.whilst(
@ -1015,7 +1022,13 @@ function handleClientReady(client, message)
return callback(); return callback();
//Check if this author is already on the pad, if yes, kick the other sessions! //Check if this author is already on the pad, if yes, kick the other sessions!
var roomClients = socketio.sockets.clients(padIds.padId); var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
for(var i = 0; i < roomClients.length; i++) { for(var i = 0; i < roomClients.length; i++) {
var sinfo = sessioninfos[roomClients[i].id]; var sinfo = sessioninfos[roomClients[i].id];
if(sinfo && sinfo.author == author) { if(sinfo && sinfo.author == author) {
@ -1032,19 +1045,19 @@ function handleClientReady(client, message)
sessioninfos[client.id].readonly = padIds.readonly; sessioninfos[client.id].readonly = padIds.readonly;
//Log creation/(re-)entering of a pad //Log creation/(re-)entering of a pad
client.get('remoteAddress', function(er, ip) { var ip = remoteAddress[client.id];
//Anonymize the IP address if IP logging is disabled
if(settings.disableIPlogging) {
ip = 'ANONYMOUS';
}
if(pad.head > 0) { //Anonymize the IP address if IP logging is disabled
accessLogger.info('[ENTER] Pad "'+padIds.padId+'": Client '+client.id+' with IP "'+ip+'" entered the pad'); if(settings.disableIPlogging) {
} ip = 'ANONYMOUS';
else if(pad.head == 0) { }
accessLogger.info('[CREATE] Pad "'+padIds.padId+'": Client '+client.id+' with IP "'+ip+'" created the pad');
} if(pad.head > 0) {
}) accessLogger.info('[ENTER] Pad "'+padIds.padId+'": Client '+client.id+' with IP "'+ip+'" entered the pad');
}
else if(pad.head == 0) {
accessLogger.info('[CREATE] Pad "'+padIds.padId+'": Client '+client.id+' with IP "'+ip+'" created the pad');
}
//If this is a reconnect, we don't have to send the client the ClientVars again //If this is a reconnect, we don't have to send the client the ClientVars again
if(message.reconnect == true) if(message.reconnect == true)
@ -1165,7 +1178,14 @@ function handleClientReady(client, message)
client.broadcast.to(padIds.padId).json.send(messageToTheOtherUsers); client.broadcast.to(padIds.padId).json.send(messageToTheOtherUsers);
//Run trough all sessions of this pad //Run trough all sessions of this pad
async.forEach(socketio.sockets.clients(padIds.padId), function(roomClient, callback) var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
async.forEach(roomClients, function(roomClient, callback)
{ {
var author; var author;

View file

@ -24,6 +24,7 @@ var log4js = require('log4js');
var messageLogger = log4js.getLogger("message"); var messageLogger = log4js.getLogger("message");
var securityManager = require("../db/SecurityManager"); var securityManager = require("../db/SecurityManager");
var readOnlyManager = require("../db/ReadOnlyManager"); var readOnlyManager = require("../db/ReadOnlyManager");
var remoteAddress = require("../utils/RemoteAddress").remoteAddress;
var settings = require('../utils/Settings'); var settings = require('../utils/Settings');
/** /**
@ -56,11 +57,15 @@ exports.setSocketIO = function(_socket) {
socket.sockets.on('connection', function(client) socket.sockets.on('connection', function(client)
{ {
// Broken: See http://stackoverflow.com/questions/4647348/send-message-to-specific-client-with-socket-io-and-node-js
// Fixed by having a persistant object, ideally this would actually be in the database layer
// TODO move to database layer
if(settings.trustProxy && client.handshake.headers['x-forwarded-for'] !== undefined){ if(settings.trustProxy && client.handshake.headers['x-forwarded-for'] !== undefined){
client.set('remoteAddress', client.handshake.headers['x-forwarded-for']); remoteAddress[client.id] = client.handshake.headers['x-forwarded-for'];
} }
else{ else{
client.set('remoteAddress', client.handshake.address.address); remoteAddress[client.id] = client.handshake.address;
} }
var clientAuthorized = false; var clientAuthorized = false;

View file

@ -1,10 +1,17 @@
var log4js = require('log4js'); var log4js = require('log4js');
var socketio = require('socket.io');
var settings = require('../../utils/Settings'); var settings = require('../../utils/Settings');
var socketIORouter = require("../../handler/SocketIORouter"); var socketIORouter = require("../../handler/SocketIORouter");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess"); var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess");
// there shouldn't be a browser that isn't compatible to all
// transports in this list at once
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
var socketio = require('socket.io')({
transports: settings.socketTransportProtocols
});
var padMessageHandler = require("../../handler/PadMessageHandler"); var padMessageHandler = require("../../handler/PadMessageHandler");
var connect = require('connect'); var connect = require('connect');
@ -16,7 +23,9 @@ exports.expressCreateServer = function (hook_name, args, cb) {
/* Require an express session cookie to be present, and load the /* Require an express session cookie to be present, and load the
* session. See http://www.danielbaulig.de/socket-ioexpress for more * session. See http://www.danielbaulig.de/socket-ioexpress for more
* info */ * info */
io.set('authorization', function (data, accept) {
io.use(function(socket, accept) {
var data = socket.request;
if (!data.headers.cookie) return accept('No session cookie transmitted.', false); if (!data.headers.cookie) return accept('No session cookie transmitted.', false);
// Use connect's cookie parser, because it knows how to parse signed cookies // Use connect's cookie parser, because it knows how to parse signed cookies
@ -36,35 +45,17 @@ exports.expressCreateServer = function (hook_name, args, cb) {
}); });
}); });
// there shouldn't be a browser that isn't compatible to all // var socketIOLogger = log4js.getLogger("socket.io");
// transports in this list at once // Debug logging now has to be set at an environment level, this is stupid.
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling // https://github.com/Automattic/socket.io/wiki/Migrating-to-1.0
io.set('transports', settings.socketTransportProtocols ); // This debug logging environment is set in Settings.js
var socketIOLogger = log4js.getLogger("socket.io");
io.set('logger', {
debug: function (str)
{
socketIOLogger.debug.apply(socketIOLogger, arguments);
},
info: function (str)
{
socketIOLogger.info.apply(socketIOLogger, arguments);
},
warn: function (str)
{
socketIOLogger.warn.apply(socketIOLogger, arguments);
},
error: function (str)
{
socketIOLogger.error.apply(socketIOLogger, arguments);
},
});
//minify socket.io javascript //minify socket.io javascript
if(settings.minify) // Due to a shitty decision by the SocketIO team minification is
io.enable('browser client minification'); // no longer available, details available at:
// http://stackoverflow.com/questions/23981741/minify-socket-io-socket-io-js-with-1-0
// if(settings.minify) io.enable('browser client minification');
//Initalize the Socket.IO Router //Initalize the Socket.IO Router
socketIORouter.setSocketIO(io); socketIORouter.setSocketIO(io);
socketIORouter.addComponent("pad", padMessageHandler); socketIORouter.addComponent("pad", padMessageHandler);

View file

@ -0,0 +1 @@
exports.remoteAddress = {};

View file

@ -228,6 +228,7 @@ exports.reloadSettings = function reloadSettings() {
log4js.configure(exports.logconfig);//Configure the logging appenders log4js.configure(exports.logconfig);//Configure the logging appenders
log4js.setGlobalLogLevel(exports.loglevel);//set loglevel log4js.setGlobalLogLevel(exports.loglevel);//set loglevel
process.env['DEBUG'] = 'socket.io:' + exports.loglevel; // Used by SocketIO for Debug
log4js.replaceConsole(); log4js.replaceConsole();
if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here

View file

@ -15,9 +15,9 @@
"request" : "2.9.100", "request" : "2.9.100",
"require-kernel" : "1.0.5", "require-kernel" : "1.0.5",
"resolve" : ">=1.0.0", "resolve" : ">=1.0.0",
"socket.io" : "0.9.x", "socket.io" : ">=1.2.0",
"ueberDB" : ">=0.2.9", "ueberDB" : ">=0.2.9",
"express" : "3.1.0", "express" : ">3.1.0 <3.9.0",
"async" : "0.1.x", "async" : "0.1.x",
"connect" : "2.7.x", "connect" : "2.7.x",
"clean-css" : "0.3.2", "clean-css" : "0.3.2",