2015-02-10 19:41:24 +00:00
|
|
|
var utils = require("connect/lib/utils");
|
|
|
|
var netutil = require("netutil");
|
|
|
|
var connect = require("connect");
|
|
|
|
var http = require("http");
|
|
|
|
var https = require("https");
|
|
|
|
|
|
|
|
module.exports = function startup(options, imports, register) {
|
|
|
|
var globalOptions = options.globals ? merge([options.globals]) : {};
|
|
|
|
|
|
|
|
var requestMethods = {};
|
|
|
|
var responseMethods = {};
|
|
|
|
|
|
|
|
var app = connect();
|
|
|
|
|
|
|
|
var hookNames = [
|
|
|
|
"Start",
|
|
|
|
"Setup",
|
|
|
|
"Main",
|
|
|
|
"Session"
|
|
|
|
];
|
|
|
|
var api = {
|
|
|
|
getModule: function() {
|
|
|
|
return connect;
|
|
|
|
},
|
|
|
|
getUtils: function() {
|
|
|
|
return utils;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* set per request options. Used e.g. for the view rendering
|
|
|
|
*/
|
|
|
|
setOptions: function(options) {
|
|
|
|
return function(req, res, next) {
|
|
|
|
res.setOptions(options);
|
|
|
|
next();
|
|
|
|
};
|
|
|
|
},
|
|
|
|
resetOptions: function() {
|
|
|
|
return function(req, res, next) {
|
|
|
|
res.resetOptions();
|
|
|
|
next();
|
|
|
|
};
|
|
|
|
},
|
|
|
|
setGlobalOption: function(key, value) {
|
|
|
|
globalOptions[key] = value;
|
|
|
|
},
|
|
|
|
getGlobalOption: function(key) {
|
|
|
|
return globalOptions[key];
|
|
|
|
},
|
|
|
|
addResponseMethod: function(name, method) {
|
|
|
|
responseMethods[name] = method;
|
|
|
|
},
|
|
|
|
addRequestMethod: function(name, method) {
|
|
|
|
requestMethods[name] = method;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
api.addResponseMethod("setOptions", function(options) {
|
|
|
|
this._options = this._options || [];
|
|
|
|
this._options.push(options);
|
|
|
|
});
|
|
|
|
|
|
|
|
api.addResponseMethod("getOptions", function(options) {
|
|
|
|
var opts = [globalOptions].concat(this._options || []);
|
|
|
|
if (options)
|
|
|
|
opts = opts.concat(options);
|
|
|
|
|
|
|
|
return merge(opts);
|
|
|
|
});
|
|
|
|
|
|
|
|
api.addResponseMethod("resetOptions", function() {
|
|
|
|
if (this._options)
|
|
|
|
this._options.pop();
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
hookNames.forEach(function(name) {
|
|
|
|
var hookServer = connect();
|
|
|
|
app.use(hookServer);
|
|
|
|
api["use" + name] = hookServer.use.bind(hookServer);
|
|
|
|
});
|
|
|
|
|
|
|
|
var connectHook = connectError();
|
|
|
|
app.use(connectHook);
|
|
|
|
api.useError = connectHook.use;
|
|
|
|
|
|
|
|
api.useSetup(connect.cookieParser());
|
|
|
|
api.useSetup(connect.urlencoded());
|
|
|
|
api.useSetup(connect.json());
|
|
|
|
|
|
|
|
api.addRoute = app.addRoute;
|
|
|
|
api.use = api.useMain;
|
|
|
|
|
|
|
|
api.on = app.on;
|
|
|
|
api.emit = app.emit;
|
|
|
|
|
|
|
|
api.useSetup(function(req, res, next) {
|
|
|
|
for (var name in requestMethods)
|
|
|
|
req[name] = requestMethods[name];
|
|
|
|
|
|
|
|
for (var name in responseMethods)
|
|
|
|
res[name] = responseMethods[name];
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
|
|
|
|
function startListening (port, host) {
|
|
|
|
api.getPort = function () {
|
|
|
|
return port;
|
|
|
|
};
|
|
|
|
api.getHost = function () {
|
|
|
|
return host;
|
|
|
|
};
|
|
|
|
|
|
|
|
var server;
|
|
|
|
var proto;
|
|
|
|
if (options.secure) {
|
|
|
|
proto = "https";
|
|
|
|
server = https.createServer(options.secure , app);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
proto = "http";
|
|
|
|
server = http.createServer(app);
|
|
|
|
}
|
|
|
|
|
|
|
|
server.listen(port, host, function(err) {
|
|
|
|
if (err)
|
|
|
|
return register(err);
|
|
|
|
|
2015-03-03 17:08:52 +00:00
|
|
|
console.log("Connect server listening at " + proto + "://"
|
|
|
|
+ (host == "0.0.0.0" && options.showRealIP
|
|
|
|
? getLocalIPs()[0]
|
|
|
|
: host) + ":" + port);
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
register(null, {
|
|
|
|
"onDestruct": function(callback) {
|
|
|
|
app.close();
|
|
|
|
app.on("close", callback);
|
|
|
|
},
|
|
|
|
"connect": api,
|
|
|
|
"http": {
|
|
|
|
getServer: function() {
|
|
|
|
return server;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
if (options.websocket)
|
|
|
|
attachWsServer(server, app);
|
|
|
|
|
|
|
|
function attachWsServer(server, app) {
|
|
|
|
server.on("upgrade", function(req, socket, head) {
|
|
|
|
var res = new http.ServerResponse(req);
|
|
|
|
req.ws = {
|
|
|
|
socket: socket,
|
|
|
|
head: head
|
|
|
|
};
|
|
|
|
req.method = "UPGRADE";
|
|
|
|
|
|
|
|
res.write = function() {
|
|
|
|
// console.log("RES WRITE", arguments);
|
|
|
|
};
|
|
|
|
res.writeHead = function() {
|
|
|
|
// console.log("RES WRITEHEAD", arguments);
|
|
|
|
};
|
|
|
|
res.end = function() {
|
|
|
|
// console.log("RES END", arguments);
|
|
|
|
socket.end();
|
|
|
|
};
|
|
|
|
|
|
|
|
app.handle(req, res, function(err) {
|
|
|
|
if (err) {
|
|
|
|
console.error("Websocket error", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
socket.end();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.port instanceof Array) {
|
|
|
|
netutil.findFreePort(options.port[0], options.port[1], options.host, function(err, port) {
|
|
|
|
if (err)
|
|
|
|
return register(err);
|
|
|
|
|
|
|
|
startListening(port, options.host || "localhost");
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
startListening(options.port, options.host || "localhost");
|
|
|
|
}
|
|
|
|
|
|
|
|
function connectError() {
|
|
|
|
var filters = [];
|
|
|
|
|
|
|
|
function handle(err, req, res, out) {
|
|
|
|
var rest = filters.concat();
|
|
|
|
|
|
|
|
function next(err) {
|
|
|
|
var filter = rest.shift();
|
|
|
|
if (!filter)
|
|
|
|
return out(err);
|
|
|
|
|
|
|
|
filter(err, req, res, next);
|
|
|
|
}
|
|
|
|
next(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
handle.use = function(middleware) {
|
|
|
|
filters.push(middleware);
|
|
|
|
};
|
|
|
|
|
|
|
|
return handle;
|
|
|
|
}
|
2015-03-03 17:08:52 +00:00
|
|
|
|
|
|
|
function getLocalIPs() {
|
|
|
|
var os = require("os");
|
|
|
|
|
|
|
|
var interfaces = os.networkInterfaces ? os.networkInterfaces() : {};
|
|
|
|
var addresses = [];
|
|
|
|
for (var k in interfaces) {
|
|
|
|
for (var k2 in interfaces[k]) {
|
|
|
|
var address = interfaces[k][k2];
|
|
|
|
if (address.family === "IPv4" && !address.internal) {
|
|
|
|
addresses.push(address.address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return addresses;
|
|
|
|
}
|
2015-02-10 19:41:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
function merge(objects) {
|
|
|
|
var result = {};
|
|
|
|
for (var i=0; i<objects.length; i++) {
|
|
|
|
var obj = objects[i];
|
|
|
|
for (var key in obj) {
|
|
|
|
result[key] = obj[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|