diff --git a/local-cli/server/runServer.js b/local-cli/server/runServer.js index ab6e54baf..323219bda 100644 --- a/local-cli/server/runServer.js +++ b/local-cli/server/runServer.js @@ -26,8 +26,10 @@ const defaultSourceExts = require('metro-bundler/build/defaults').sourceExts; const defaultPlatforms = require('metro-bundler/build/defaults').platforms; const defaultProvidesModuleNodeModules = require('metro-bundler/build/defaults') .providesModuleNodeModules; +const fs = require('fs'); const getDevToolsMiddleware = require('./middleware/getDevToolsMiddleware'); const http = require('http'); +const https = require('https'); const indexPageMiddleware = require('./middleware/indexPage'); const loadRawBodyMiddleware = require('./middleware/loadRawBodyMiddleware'); const messageSocket = require('./util/messageSocket.js'); @@ -89,23 +91,32 @@ function runServer( app.use(connect.logger()).use(connect.errorHandler()); - const serverInstance = http - .createServer(app) - .listen(args.port, args.host, 511, function() { - attachHMRServer({ - httpServer: serverInstance, - path: '/hot', - packagerServer, - }); + if (args.https && (!args.key || !args.cert)) { + throw new Error('Cannot use https without specifying key and cert options'); + } - wsProxy = webSocketProxy.attachToServer( - serverInstance, - '/debugger-proxy', - ); - ms = messageSocket.attachToServer(serverInstance, '/message'); - inspectorProxy.attachToServer(serverInstance, '/inspector'); - readyCallback(packagerServer._reporter); + const serverInstance = args.https + ? https.createServer( + { + key: fs.readFileSync(args.key), + cert: fs.readFileSync(args.cert), + }, + app, + ) + : http.createServer(app); + + serverInstance.listen(args.port, args.host, 511, function() { + attachHMRServer({ + httpServer: serverInstance, + path: '/hot', + packagerServer, }); + + wsProxy = webSocketProxy.attachToServer(serverInstance, '/debugger-proxy'); + ms = messageSocket.attachToServer(serverInstance, '/message'); + inspectorProxy.attachToServer(serverInstance, '/inspector'); + readyCallback(packagerServer._reporter); + }); // Disable any kind of automatic timeout behavior for incoming // requests in case it takes the packager more than the default // timeout of 120 seconds to respond to a request. diff --git a/local-cli/server/server.js b/local-cli/server/server.js index 1cdd8b8ec..b7a4c02dd 100644 --- a/local-cli/server/server.js +++ b/local-cli/server/server.js @@ -121,5 +121,14 @@ module.exports = { }, { command: '--verbose', description: 'Enables logging', + }, { + command: '--https', + description: 'Enables https connections to the server', + }, { + command: '--key [path]', + description: 'Path to custom SSL key', + }, { + command: '--cert [path]', + description: 'Path to custom SSL cert', }], }; diff --git a/local-cli/server/util/attachHMRServer.js b/local-cli/server/util/attachHMRServer.js index da80fcdef..e24489180 100644 --- a/local-cli/server/util/attachHMRServer.js +++ b/local-cli/server/util/attachHMRServer.js @@ -17,6 +17,7 @@ const url = require('url'); import type {ResolutionResponse} from './getInverseDependencies'; import type {Server as HTTPServer} from 'http'; +import type {Server as HTTPSServer} from 'https'; const blacklist = [ 'Libraries/Utilities/HMRClient.js', @@ -57,7 +58,7 @@ type PackagerServer = { }; type HMROptions = { - httpServer: HTTPServer, + httpServer: HTTPServer | HTTPSServer, packagerServer: PackagerServer, path: string, }; diff --git a/local-cli/server/util/inspectorProxy.js b/local-cli/server/util/inspectorProxy.js index 092f87b2a..d4675d8af 100644 --- a/local-cli/server/util/inspectorProxy.js +++ b/local-cli/server/util/inspectorProxy.js @@ -48,6 +48,8 @@ const WebSocket = require('ws'); const debug = require('debug')('RNP:InspectorProxy'); const launchChrome = require('./launchChrome'); +import type {Server as HTTPSServer} from 'https'; + type DevicePage = { id: string, title: string, @@ -94,6 +96,8 @@ type Address = { port: number, }; +type Server = http.Server | HTTPSServer; + const DEVICE_TIMEOUT = 30000; // FIXME: This is the url we want to use as it more closely matches the actual protocol we use. @@ -280,7 +284,7 @@ class InspectorProxy { this._devicesCounter = 0; } - attachToServer(server: http.Server, pathPrefix: string) { + attachToServer(server: Server, pathPrefix: string) { this._createPageHandler(server, pathPrefix + '/page'); this._createDeviceHandler(server, pathPrefix + '/device'); this._createPagesListHandler(server, pathPrefix + '/'); @@ -324,7 +328,7 @@ class InspectorProxy { } } - _createDeviceHandler(server: http.Server, path: string) { + _createDeviceHandler(server: Server, path: string) { const wss = new WebSocket.Server({ server, path, @@ -347,7 +351,7 @@ class InspectorProxy { }); } - _createPageHandler(server: http.Server, path: string) { + _createPageHandler(server: Server, path: string) { const wss = new WebSocket.Server({ server, path, @@ -373,7 +377,7 @@ class InspectorProxy { }); } - _createPagesJsonHandler(server: http.Server, path: string) { + _createPagesJsonHandler(server: Server, path: string) { server.on('request', (request: http.IncomingMessage, response: http.ServerResponse) => { if (request.url === path) { this._getPages(server.address()).then((result: Array) => { @@ -387,7 +391,7 @@ class InspectorProxy { }); } - _createPagesListHandler(server: http.Server, path: string) { + _createPagesListHandler(server: Server, path: string) { server.on('request', (request: http.IncomingMessage, response: http.ServerResponse) => { if (request.url === path) { this._getPages(server.address()).then((result: Array) => {