Merge pull request #1003 from Pita/express-v3

Upgrade Express to v3 [proposal]
This commit is contained in:
John McLear 2012-10-03 06:25:44 -07:00
commit 66475f32f3
11 changed files with 61 additions and 45 deletions

View File

@ -49,7 +49,8 @@ Called from: src/node/server.js
Things in context: Things in context:
1. app - the main application object (helpful for adding new paths and such) 1. app - the main express application object (helpful for adding new paths and such)
2. server - the http server object
This hook gets called after the application object has been created, but before it starts listening. This is similar to the expressConfigure hook, but it's not guaranteed that the application object will have all relevant configuration variables. This hook gets called after the application object has been created, but before it starts listening. This is similar to the expressConfigure hook, but it's not guaranteed that the application object will have all relevant configuration variables.
@ -71,6 +72,7 @@ Things in context:
1. app - the application object 1. app - the application object
2. io - the socketio object 2. io - the socketio object
3. server - the http server object
I have no idea what this is useful for, someone else will have to add this description. I have no idea what this is useful for, someone else will have to add this description.

View File

@ -1,4 +1,5 @@
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var http = require('http');
var express = require('express'); var express = require('express');
var settings = require('../utils/Settings'); var settings = require('../utils/Settings');
var fs = require('fs'); var fs = require('fs');
@ -42,22 +43,24 @@ exports.createServer = function () {
} }
exports.restartServer = function () { exports.restartServer = function () {
if (server) { if (server) {
console.log("Restarting express server"); console.log("Restarting express server");
server.close(); server.close();
} }
server = express.createServer(); var app = express(); // New syntax for express v3
server = http.createServer(app);
server.use(function (req, res, next) { app.use(function (req, res, next) {
res.header("Server", serverName); res.header("Server", serverName);
next(); next();
}); });
server.configure(function() { app.configure(function() {
hooks.callAll("expressConfigure", {"app": server}); hooks.callAll("expressConfigure", {"app": app});
}); });
hooks.callAll("expressCreateServer", {"app": server}); hooks.callAll("expressCreateServer", {"app": app, "server": server});
server.listen(settings.port, settings.ip); server.listen(settings.port, settings.ip);
} }

View File

@ -12,14 +12,10 @@ exports.expressCreateServer = function (hook_name, args, cb) {
errors: [], errors: [],
}; };
res.send(eejs.require( res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins.html", render_args) );
"ep_etherpad-lite/templates/admin/plugins.html",
render_args), {});
}); });
args.app.get('/admin/plugins/info', function(req, res) { args.app.get('/admin/plugins/info', function(req, res) {
res.send(eejs.require( res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {}) );
"ep_etherpad-lite/templates/admin/plugins-info.html",
{}), {});
}); });
} }

View File

@ -16,9 +16,6 @@ exports.gracefulShutdown = function(err) {
console.log("graceful shutdown..."); console.log("graceful shutdown...");
//stop the http server
exports.app.close();
//do the db shutdown //do the db shutdown
db.db.doShutdown(function() { db.db.doShutdown(function() {
console.log("db sucessfully closed."); console.log("db sucessfully closed.");
@ -35,10 +32,14 @@ exports.gracefulShutdown = function(err) {
exports.expressCreateServer = function (hook_name, args, cb) { exports.expressCreateServer = function (hook_name, args, cb) {
exports.app = args.app; exports.app = args.app;
args.app.error(function(err, req, res, next){ // Handle errors
res.send(500); args.app.use(function(err, req, res, next){
console.error(err.stack ? err.stack : err.toString()); // if an error occurs Connect will pass it down
}); // through these "error-handling" middleware
// allowing you to respond however you like
res.send(500, { error: 'Sorry, something bad happened!' });
console.error(err.stack? err.stack : err.toString());
})
//connect graceful shutdown with sigint and uncaughtexception //connect graceful shutdown with sigint and uncaughtexception
if(os.type().indexOf("Windows") == -1) { if(os.type().indexOf("Windows") == -1) {

View File

@ -56,7 +56,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
ERR(err); ERR(err);
if(err == "notfound") if(err == "notfound")
res.send('404 - Not Found', 404); res.send(404, '404 - Not Found');
else else
res.send(html); res.send(html);
}); });

View File

@ -7,7 +7,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
//ensure the padname is valid and the url doesn't end with a / //ensure the padname is valid and the url doesn't end with a /
if(!padManager.isValidPadId(padId) || /\/$/.test(req.url)) if(!padManager.isValidPadId(padId) || /\/$/.test(req.url))
{ {
res.send('Such a padname is forbidden', 404); res.send(404, 'Such a padname is forbidden');
} }
else else
{ {
@ -19,7 +19,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
var query = url.parse(req.url).query; var query = url.parse(req.url).query;
if ( query ) real_url += '?' + query; if ( query ) real_url += '?' + query;
res.header('Location', real_url); res.header('Location', real_url);
res.send('You should be redirected to <a href="' + real_url + '">' + real_url + '</a>', 302); res.send(302, 'You should be redirected to <a href="' + real_url + '">' + real_url + '</a>');
} }
//the pad id was fine, so just render it //the pad id was fine, so just render it
else else

View File

@ -3,6 +3,7 @@ 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 padMessageHandler = require("../../handler/PadMessageHandler"); var padMessageHandler = require("../../handler/PadMessageHandler");
@ -10,19 +11,28 @@ var connect = require('connect');
exports.expressCreateServer = function (hook_name, args, cb) { exports.expressCreateServer = function (hook_name, args, cb) {
//init socket.io and redirect all requests to the MessageHandler //init socket.io and redirect all requests to the MessageHandler
var io = socketio.listen(args.app); var io = socketio.listen(args.server);
/* 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.set('authorization', function (data, accept) {
if (!data.headers.cookie) return accept('No session cookie transmitted.', false); if (!data.headers.cookie) return accept('No session cookie transmitted.', false);
data.cookie = connect.utils.parseCookie(data.headers.cookie);
data.sessionID = data.cookie.express_sid; // Use connect's cookie parser, because it knows how to parse signed cookies
args.app.sessionStore.get(data.sessionID, function (err, session) { connect.cookieParser(webaccess.secret)(data, {}, function(err){
if (err || !session) return accept('Bad session / session has expired', false); if(err) {
data.session = new connect.middleware.session.Session(data, session); console.error(err);
accept(null, true); accept("Couldn't parse request cookies. ", false);
return;
}
data.sessionID = data.signedCookies.express_sid;
args.app.sessionStore.get(data.sessionID, function (err, session) {
if (err || !session) return accept('Bad session / session has expired', false);
data.session = new connect.middleware.session.Session(data, session);
accept(null, true);
});
}); });
}); });
@ -62,5 +72,5 @@ exports.expressCreateServer = function (hook_name, args, cb) {
socketIORouter.setSocketIO(io); socketIORouter.setSocketIO(io);
socketIORouter.addComponent("pad", padMessageHandler); socketIORouter.addComponent("pad", padMessageHandler);
hooks.callAll("socketio", {"app": args.app, "io": io}); hooks.callAll("socketio", {"app": args.app, "io": io, "server": args.server});
} }

View File

@ -56,10 +56,10 @@ exports.basicAuth = function (req, res, next) {
res.header('WWW-Authenticate', 'Basic realm="Protected Area"'); res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
if (req.headers.authorization) { if (req.headers.authorization) {
setTimeout(function () { setTimeout(function () {
res.send('Authentication required', 401); res.send(401, 'Authentication required');
}, 1000); }, 1000);
} else { } else {
res.send('Authentication required', 401); res.send(401, 'Authentication required');
} }
})); }));
} }
@ -88,14 +88,13 @@ exports.basicAuth = function (req, res, next) {
}); });
} }
var secret = null; exports.secret = null;
exports.expressConfigure = function (hook_name, args, cb) { exports.expressConfigure = function (hook_name, args, cb) {
// If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158. // If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
// Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway. // Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR")) if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR"))
args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'})); args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'}));
args.app.use(express.cookieParser());
/* Do not let express create the session, so that we can retain a /* Do not let express create the session, so that we can retain a
* reference to it for socket.io to use. Also, set the key (cookie * reference to it for socket.io to use. Also, set the key (cookie
@ -104,13 +103,14 @@ exports.expressConfigure = function (hook_name, args, cb) {
if (!exports.sessionStore) { if (!exports.sessionStore) {
exports.sessionStore = new express.session.MemoryStore(); exports.sessionStore = new express.session.MemoryStore();
secret = randomString(32); exports.secret = randomString(32);
} }
args.app.use(express.cookieParser(exports.secret));
args.app.sessionStore = exports.sessionStore; args.app.sessionStore = exports.sessionStore;
args.app.use(express.session({store: args.app.sessionStore, args.app.use(express.session({store: args.app.sessionStore,
key: 'express_sid', key: 'express_sid' }));
secret: secret}));
args.app.use(exports.basicAuth); args.app.use(exports.basicAuth);
} }

View File

@ -15,7 +15,7 @@ module.exports = function (req, res, callback) {
callback(); callback();
//no access //no access
} else { } else {
res.send("403 - Can't touch this", 403); res.send(403, "403 - Can't touch this");
} }
}); });
} }

View File

@ -21,8 +21,15 @@
* limitations under the License. * limitations under the License.
*/ */
// set up logger
var log4js = require('log4js'); var log4js = require('log4js');
log4js.replaceConsole();
var settings = require('./utils/Settings'); var settings = require('./utils/Settings');
//set loglevel
log4js.setGlobalLogLevel(settings.loglevel);
var db = require('./db/DB'); var db = require('./db/DB');
var async = require('async'); var async = require('async');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
@ -31,9 +38,6 @@ var npm = require("npm/lib/npm.js");
hooks.plugins = plugins; hooks.plugins = plugins;
//set loglevel
log4js.setGlobalLogLevel(settings.loglevel);
async.waterfall([ async.waterfall([
//initalize the database //initalize the database
function (callback) function (callback)

View File

@ -17,12 +17,12 @@
"socket.io" : "0.9.x", "socket.io" : "0.9.x",
"ueberDB" : "0.1.7", "ueberDB" : "0.1.7",
"async" : "0.1.x", "async" : "0.1.x",
"express" : "2.5.x", "express" : "3.x",
"connect" : "1.x", "connect" : "2.4.x",
"clean-css" : "0.3.2", "clean-css" : "0.3.2",
"uglify-js" : "1.2.5", "uglify-js" : "1.2.5",
"formidable" : "1.0.9", "formidable" : "1.0.9",
"log4js" : "0.4.1", "log4js" : "0.5.x",
"jsdom-nocontextifiy" : "0.2.10", "jsdom-nocontextifiy" : "0.2.10",
"async-stacktrace" : "0.0.2", "async-stacktrace" : "0.0.2",
"npm" : "1.1.24", "npm" : "1.1.24",