meteor-bundle-main.js
Rama master · réplica de lectura del repositorio original.
// Typically, Meteor binds to one port and speaks HTTP.
//
// For Sandstorm, `run-bundle` has already bound a number of TCP ports
// for us and passed them in as file descriptors starting at #3. So
// this file runs before Meteor starts, monkey-patching the node world
// so that, along with pre-meteor.js, we create the the right
// HTTP+HTTPS services.
var http = require('http');
var net = require('net');
var isDevShellMode = process.argv.length > 2;
var firstInheritedFd = isDevShellMode ? 65 : 3;
function sandstormMain() {
process.env.SANDSTORM_SMTP_LISTEN_HANDLE = (firstInheritedFd + 2).toString();
process.env.SANDSTORM_BACKEND_HANDLE = (firstInheritedFd + 1).toString();
monkeypatchHttpForGateway();
if (isDevShellMode) {
// Cut ourselves out of argv.
process.argv = [process.argv[0]].concat(process.argv.slice(2));
// Change to the shell directory, which Meteor expects.
process.chdir("shell");
// Delegate to Meteor dev tool.
require(process.argv[1]);
} else {
// Delegate to Meteor runtime.
require("./main.js");
}
}
function monkeypatchHttpForGateway() {
// Monkey-patch the HTTP server module to receive connections over a unix socket on FD 3 instead
// of listening the usual way.
if (process.env.HTTP_GATEWAY === "local") {
// Node.js has no public API for receiving file descriptors via SCM_RIGHTS on a unix pipe.
// However, it does have a *private* API for this, which it uses to implement child_process.
// We use the private API here. This could break when we update Node. If so, that's our fault.
// But we pin our Node version, so this should be easy to control. Also, this interface hasn't
// changed in forever.
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');
global.sandstormListenCapabilityStream = function (fd, cb) {
var pipe = new Pipe(PipeConstants.IPC);
pipe.open(fd);
pipe.onread = function (buf) {
let handle = pipe.pendingHandle;
if (handle) {
pipe.pendingHandle = null;
cb(new net.Socket({ handle: handle, readable: true, writable: true }));
}
};
pipe.readStart();
}
}
var oldListen = http.Server.prototype.listen;
var alreadyListened = false;
http.Server.prototype.listen = function (port, host, cb) {
if (port.toString() === process.env.PORT ||
(typeof port === "object" && port.port && port.port.toString() === process.env.PORT)) {
// Attempt to listen on the HTTP port. Override.
if (alreadyListened) {
throw new Error("can only listen on primary HTTP port once");
}
alreadyListened = true;
if (process.env.HTTP_GATEWAY === "local") {
// Gateway running locally, connecting over unix socketpair via SCM_RIGHTS transfer.
global.sandstormListenCapabilityStream(firstInheritedFd, socket => {
this.emit("connection", socket);
});
(cb || host)();
} else {
// Gateway running remotely, connecting over a regular socket.
oldListen.call(this, { fd: firstInheritedFd }, cb || host);
}
} else {
// Don't override.
return oldListen.call(this, port, host, cb);
}
}
}
sandstormMain();