Support implicit init and SDK proxy in firebase serve

This commit is contained in:
Michael Bleigh
2017-03-16 11:11:37 -07:00
committed by GitHub
parent 33f4363c39
commit 4d30ca1ce4
4 changed files with 91 additions and 33 deletions

View File

@@ -6,45 +6,55 @@ var superstatic = require('superstatic').server;
var Command = require('../lib/command');
var FirebaseError = require('../lib/error');
var hostingImplicitInit = require('../lib/hostingImplicitInit');
var hostingInitMiddleware = require('../lib/hostingInitMiddleware');
var logger = require('../lib/logger');
var utils = require('../lib/utils');
var requireAccess = require('../lib/requireAccess');
var requireConfig = require('../lib/requireConfig');
var checkDupHostingKeys = require('../lib/checkDupHostingKeys');
var scopes = require('../lib/scopes');
var MAX_PORT_ATTEMPTS = 10;
var _attempts = 0;
var startServer = function(options) {
var config = options.config ? options.config.get('hosting') : {public: '.'};
var server = superstatic({
debug: true,
port: options.port,
host: options.host,
config: config,
stack: 'strict'
}).listen(function() {
if (config.public && config.public !== '.') {
logger.info(chalk.bold('Public Directory:'), config.public);
}
logger.info();
logger.info('Server listening at: ' + chalk.underline(chalk.bold('http://' + options.host + ':' + options.port)));
});
server.on('error', function(err) {
if (err.code === 'EADDRINUSE') {
var message = 'Port ' + options.port + ' is not available.';
if (_attempts < MAX_PORT_ATTEMPTS) {
utils.logWarning(message + ' Trying another port...');
options.port++;
_attempts++;
startServer(options);
} else {
utils.logWarning(message);
throw new FirebaseError('Could not find an open port for development server.', {exit: 1});
return hostingImplicitInit(options).then(function(init) {
var server = superstatic({
debug: true,
port: options.port,
host: options.host,
config: config,
stack: 'strict',
before: {
files: hostingInitMiddleware(init)
}
} else {
throw new FirebaseError('An error occurred while starting the development server:\n\n' + err.toString(), {exit: 1});
}
}).listen(function() {
if (config.public && config.public !== '.') {
logger.info(chalk.bold('Public Directory:'), config.public);
}
logger.info();
logger.info('Server listening at: ' + chalk.underline(chalk.bold('http://' + options.host + ':' + options.port)));
});
server.on('error', function(err) {
if (err.code === 'EADDRINUSE') {
var message = 'Port ' + options.port + ' is not available.';
if (_attempts < MAX_PORT_ATTEMPTS) {
utils.logWarning(message + ' Trying another port...');
options.port++;
_attempts++;
startServer(options);
} else {
utils.logWarning(message);
throw new FirebaseError('Could not find an open port for development server.', {exit: 1});
}
} else {
throw new FirebaseError('An error occurred while starting the development server:\n\n' + err.toString(), {exit: 1});
}
});
});
};
@@ -53,6 +63,7 @@ module.exports = new Command('serve')
.option('-p, --port <port>', 'the port on which to listen (default: 5000)', 5000)
.option('-o, --host <host>', 'the host on which to listen (default: localhost)', 'localhost')
.before(requireConfig)
.before(requireAccess, [scopes.CLOUD_PLATFORM])
.before(checkDupHostingKeys)
.action(function(options) {
logger.info('Starting Firebase development server...');
@@ -64,12 +75,12 @@ module.exports = new Command('serve')
utils.logWarning('No Firebase project directory detected. Serving static content from ' + chalk.bold(options.cwd || process.cwd()));
}
startServer(options);
return new RSVP.Promise(function(resolve) {
process.on('SIGINT', function() {
logger.info('Shutting down...');
resolve();
return startServer(options).then(function() {
return new RSVP.Promise(function(resolve) {
process.on('SIGINT', function() {
logger.info('Shutting down...');
resolve();
});
});
});
});

View File

@@ -0,0 +1,17 @@
'use strict';
var fs = require('fs');
var fetchWebSetup = require('./fetchWebSetup');
var INIT_TEMPLATE = fs.readFileSync(__dirname + '/../templates/hosting/init.js', 'utf8');
module.exports = function(options) {
return fetchWebSetup(options).then(function(config) {
var configJson = JSON.stringify(config, null, 2);
return {
js: INIT_TEMPLATE.replace('{/*--CONFIG--*/}', configJson),
json: configJson
};
});
};

View File

@@ -0,0 +1,28 @@
'use strict';
var request = require('request');
var SDK_PATH_REGEXP = /^\/__\/firebase\/([^/]+)\/([^/]+)$/;
module.exports = function(init) {
return function(req, res, next) {
var match = req.url.match(SDK_PATH_REGEXP);
if (match) {
var url = 'https://www.gstatic.com/firebasejs/' + match[1] + '/' + match[2];
var preq = request(url).on('response', function(pres) {
if (pres.statusCode === 404) {
return next();
}
return preq.pipe(res);
});
} else if (req.url === '/__/firebase/init.js') {
res.setHeader('Content-Type', 'application/javascript');
res.end(init.js);
} else if (req.url === '/__/firebase/init.json') {
res.setHeader('Content-Type', 'application/json');
res.end(init.json);
} else {
next();
}
};
};

View File

@@ -0,0 +1,2 @@
if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
firebase.initializeApp({/*--CONFIG--*/});