Serve on domain socket

Summary: Open a domain socket by default and proxy all browser requests via TCP to it. That allows us to connect to a running server regardless of its local port.

Reviewed By: aigoncharov

Differential Revision: D35088208

fbshipit-source-id: d167852162e63f68c804c379b4421f5cc0d33df2
This commit is contained in:
Pascal Hartig
2022-03-31 06:29:21 -07:00
committed by Facebook GitHub Bot
parent ba9a80545d
commit 56e94394ca
4 changed files with 76 additions and 8 deletions

View File

@@ -10,12 +10,15 @@
"bugs": "https://github.com/facebook/flipper/issues", "bugs": "https://github.com/facebook/flipper/issues",
"dependenciesComment": "mac-ca is required dynamically for darwin, node-fetch is treated special in electron-requires, not sure why", "dependenciesComment": "mac-ca is required dynamically for darwin, node-fetch is treated special in electron-requires, not sure why",
"dependencies": { "dependencies": {
"http-proxy": "^1.18.1",
"mac-ca": "^1.0.6", "mac-ca": "^1.0.6",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.7",
"ws": "^8.5.0" "ws": "^8.5.0",
"xdg-basedir": "^4"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/http-proxy": "^1.17.8",
"@types/node": "^15.12.5", "@types/node": "^15.12.5",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"express": "^4.17.3", "express": "^4.17.3",

View File

@@ -7,6 +7,7 @@
* @format * @format
*/ */
import os from 'os';
import express, {Express} from 'express'; import express, {Express} from 'express';
import http from 'http'; import http from 'http';
import path from 'path'; import path from 'path';
@@ -14,6 +15,10 @@ import fs from 'fs-extra';
import {VerifyClientCallbackSync, WebSocketServer} from 'ws'; import {VerifyClientCallbackSync, WebSocketServer} from 'ws';
import {WEBSOCKET_MAX_MESSAGE_SIZE} from 'flipper-server-core'; import {WEBSOCKET_MAX_MESSAGE_SIZE} from 'flipper-server-core';
import {parse} from 'url'; import {parse} from 'url';
import xdgBasedir from 'xdg-basedir';
import proxy from 'http-proxy';
import {userInfo} from 'os';
type Config = { type Config = {
port: number; port: number;
@@ -26,7 +31,7 @@ export async function startBaseServer(config: Config): Promise<{
server: http.Server; server: http.Server;
socket: WebSocketServer; socket: WebSocketServer;
}> { }> {
const {app, server} = await startAssetServer(config); const {app, server} = await startHTTPServer(config);
const socket = addWebsocket(server, config); const socket = addWebsocket(server, config);
return { return {
app, app,
@@ -35,7 +40,7 @@ export async function startBaseServer(config: Config): Promise<{
}; };
} }
function startAssetServer( async function startHTTPServer(
config: Config, config: Config,
): Promise<{app: Express; server: http.Server}> { ): Promise<{app: Express; server: http.Server}> {
const app = express(); const app = express();
@@ -59,10 +64,41 @@ function startAssetServer(
app.use(express.static(config.staticDir)); app.use(express.static(config.staticDir));
return startProxyServer(config, app);
}
async function startProxyServer(
config: Config,
app: Express,
): Promise<{app: Express; server: http.Server}> {
const server = http.createServer(app); const server = http.createServer(app);
// For now, we only support domain socket access on POSIX-like systems.
if (os.platform() === 'win32') {
return new Promise((resolve) => {
console.log(`Starting server on http://localhost:${config.port}`);
server.listen(config.port, undefined, () => resolve({app, server}));
});
}
const runtimeDir = xdgBasedir.runtime || '/tmp';
await fs.mkdirp(runtimeDir);
const socketPath = `${runtimeDir}/flipper-server-${userInfo().uid}.sock`;
// TODO: More careful cleanup.
await fs.rm(socketPath, {force: true});
const proxyServer = proxy.createProxyServer({
target: {host: 'localhost', port: 0, socketPath},
autoRewrite: true,
ws: true,
});
console.log('Starting socket server on ', socketPath);
console.log(`Starting proxy server on http://localhost:${config.port}`);
return new Promise((resolve) => { return new Promise((resolve) => {
server.listen(config.port, undefined, () => resolve({app, server})); proxyServer.listen(config.port);
server.listen(socketPath, undefined, () => resolve({app, server}));
}); });
} }

View File

@@ -23,9 +23,12 @@ export function startSocketServer(
socket: WebSocketServer, socket: WebSocketServer,
) { ) {
socket.on('connection', (client, req) => { socket.on('connection', (client, req) => {
const clientAddress = `${req.socket.remoteAddress}:${req.socket.remotePort}`; const clientAddress =
(req.socket.remoteAddress &&
` ${req.socket.remoteAddress}:${req.socket.remotePort}`) ||
'';
console.log(chalk.green(`Client connected ${clientAddress}`)); console.log(chalk.green(`Client connected${clientAddress}`));
let connected = true; let connected = true;

View File

@@ -2504,6 +2504,13 @@
"@types/react" "*" "@types/react" "*"
hoist-non-react-statics "^3.3.0" hoist-non-react-statics "^3.3.0"
"@types/http-proxy@^1.17.8":
version "1.17.8"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55"
integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==
dependencies:
"@types/node" "*"
"@types/inquirer@^7.3.3": "@types/inquirer@^7.3.3":
version "7.3.3" version "7.3.3"
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.3.tgz#92e6676efb67fa6925c69a2ee638f67a822952ac" resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.3.tgz#92e6676efb67fa6925c69a2ee638f67a822952ac"
@@ -5925,7 +5932,7 @@ event-target-shim@^5.0.0:
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
eventemitter3@^4.0.7: eventemitter3@^4.0.0, eventemitter3@^4.0.7:
version "4.0.7" version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
@@ -6351,6 +6358,11 @@ follow-redirects@1.5.10:
dependencies: dependencies:
debug "=3.1.0" debug "=3.1.0"
follow-redirects@^1.0.0:
version "1.14.9"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
follow-redirects@^1.14.8: follow-redirects@^1.14.8:
version "1.14.8" version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
@@ -6882,6 +6894,15 @@ http-proxy-agent@^5.0.0:
agent-base "6" agent-base "6"
debug "4" debug "4"
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
dependencies:
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
https-proxy-agent@^5.0.0: https-proxy-agent@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
@@ -10806,6 +10827,11 @@ requireindex@~1.1.0:
resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162"
integrity sha1-5UBLgVV+91225JxacgBIk/4D4WI= integrity sha1-5UBLgVV+91225JxacgBIk/4D4WI=
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
reselect@^4.1.5: reselect@^4.1.5:
version "4.1.5" version "4.1.5"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6" resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6"
@@ -12637,7 +12663,7 @@ ws@~8.2.3:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba"
integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==
xdg-basedir@^4.0.0: xdg-basedir@^4, xdg-basedir@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==