From bad67d0a89f6c61b2763a4f0bf1a525d4a2143e6 Mon Sep 17 00:00:00 2001 From: harkamal Date: Thu, 3 Mar 2022 14:57:50 +0530 Subject: [PATCH 1/2] Add functionality to specify cors for rpc server --- package-lock.json | 12 ++++-------- packages/client/bin/cli.ts | 5 +++++ packages/client/bin/startRpc.ts | 5 +++++ packages/client/lib/util/rpc.ts | 14 +++++++++++++- packages/client/package.json | 1 + 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bfb58e120..4a7b3db3a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4309,7 +4309,6 @@ "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, "dependencies": { "object-assign": "^4", "vary": "^1" @@ -13036,7 +13035,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -17943,7 +17941,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, "engines": { "node": ">= 0.8" } @@ -19233,6 +19230,7 @@ "body-parser": "^1.19.2", "chalk": "^4.1.2", "connect": "^3.7.0", + "cors": "^2.8.5", "debug": "^4.3.3", "ethereumjs-util": "^7.1.4", "fs-extra": "^10.0.0", @@ -20811,6 +20809,7 @@ "chalk": "^4.1.2", "connect": "^3.7.0", "constants-browserify": "^1.0.0", + "cors": "^2.8.5", "crypto-browserify": "^3.12.0", "debug": "^4.3.3", "eslint": "^6.8.0", @@ -24518,7 +24517,6 @@ "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, "requires": { "object-assign": "^4", "vary": "^1" @@ -31717,8 +31715,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-hash": { "version": "2.2.0", @@ -35647,8 +35644,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "verdaccio": { "version": "4.12.2", diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index b443eac106..6c9d6dc642 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -159,6 +159,11 @@ const args = yargs(hideBin(process.argv)) describe: 'Additionally log complete RPC calls on log level debug (i.e. --loglevel=debug)', boolean: true, }) + .option('rpcCors', { + describe: 'Configures the Access-Control-Allow-Origin CORS header for RPC server', + string: true, + default: '*', + }) .option('maxPerRequest', { describe: 'Max items per block or header request', number: true, diff --git a/packages/client/bin/startRpc.ts b/packages/client/bin/startRpc.ts index 167e56db31..6036384382 100644 --- a/packages/client/bin/startRpc.ts +++ b/packages/client/bin/startRpc.ts @@ -20,6 +20,7 @@ type RPCArgs = { helprpc: boolean 'jwt-secret'?: string rpcEngineAuth: boolean + rpcCors: string } /** @@ -104,6 +105,7 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { rpcEnginePort, 'jwt-secret': jwtSecretPath, rpcEngineAuth, + rpcCors, } = args const manager = new RPCManager(client, config) const jwtSecret = parseJwtSecret(config, jwtSecretPath) @@ -121,6 +123,7 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { if (rpc) { rpcHttpServer = createRPCServerListener({ + rpcCors, server, withEngineMiddleware: withEngineMethods && rpcEngineAuth @@ -140,6 +143,7 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { } if (ws) { const opts: any = { + rpcCors, server, withEngineMiddleware: withEngineMethods && rpcEngineAuth ? { jwtSecret } : undefined, } @@ -166,6 +170,7 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { server.on('response', onBatchResponse) createRPCServerListener({ + rpcCors, server, withEngineMiddleware: rpcEngineAuth ? { diff --git a/packages/client/lib/util/rpc.ts b/packages/client/lib/util/rpc.ts index 020d0bff39..e7cfbdcf84 100644 --- a/packages/client/lib/util/rpc.ts +++ b/packages/client/lib/util/rpc.ts @@ -3,10 +3,12 @@ import { Server as RPCServer, HttpServer } from 'jayson/promise' import { json as jsonParser } from 'body-parser' import { decode, TAlgorithm } from 'jwt-simple' import Connect, { IncomingMessage } from 'connect' +import cors from 'cors' const algorithm: TAlgorithm = 'HS256' type CreateRPCServerListenerOpts = { + rpcCors?: string server: RPCServer withEngineMiddleware?: WithEngineMiddleware } @@ -26,6 +28,7 @@ function checkHeaderAuth(req: any, jwtSecret: Buffer): void { export function createRPCServerListener(opts: CreateRPCServerListenerOpts): HttpServer { const { server, withEngineMiddleware } = opts const app = Connect() + if (opts.rpcCors) app.use(cors({ origin: opts.rpcCors })) app.use(jsonParser()) if (withEngineMiddleware) { @@ -56,7 +59,16 @@ export function createWsRPCServerListener( ): HttpServer | undefined { const { server, withEngineMiddleware } = opts // Get the server to hookup upgrade request on - const httpServer = opts.httpServer ?? createServer() + + let httpServer = opts.httpServer + if (!httpServer) { + const app = Connect() + // Incase browser pre-flights the upgrade request with an options request + // more likely in case of wss connection + if (opts.rpcCors) app.use(cors({ origin: opts.rpcCors })) + httpServer = createServer(app) + } + const wss = server.websocket({ noServer: true }) httpServer.on('upgrade', (req, socket, head) => { diff --git a/packages/client/package.json b/packages/client/package.json index ebd4bbef07..720ba5be4c 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -60,6 +60,7 @@ "body-parser": "^1.19.2", "chalk": "^4.1.2", "connect": "^3.7.0", + "cors": "^2.8.5", "debug": "^4.3.3", "ethereumjs-util": "^7.1.4", "fs-extra": "^10.0.0", From b05bc89f2481f12c791bead8b29d0152a0910ce2 Mon Sep 17 00:00:00 2001 From: Ryan Ghods Date: Thu, 3 Mar 2022 12:09:52 -0800 Subject: [PATCH 2/2] nits --- packages/client/bin/cli.ts | 2 +- packages/client/lib/util/rpc.ts | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 6c9d6dc642..4acac8f655 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -160,7 +160,7 @@ const args = yargs(hideBin(process.argv)) boolean: true, }) .option('rpcCors', { - describe: 'Configures the Access-Control-Allow-Origin CORS header for RPC server', + describe: 'Configure the Access-Control-Allow-Origin CORS header for RPC server', string: true, default: '*', }) diff --git a/packages/client/lib/util/rpc.ts b/packages/client/lib/util/rpc.ts index e7cfbdcf84..5224cca6f3 100644 --- a/packages/client/lib/util/rpc.ts +++ b/packages/client/lib/util/rpc.ts @@ -26,9 +26,10 @@ function checkHeaderAuth(req: any, jwtSecret: Buffer): void { } export function createRPCServerListener(opts: CreateRPCServerListenerOpts): HttpServer { - const { server, withEngineMiddleware } = opts + const { server, withEngineMiddleware, rpcCors } = opts + const app = Connect() - if (opts.rpcCors) app.use(cors({ origin: opts.rpcCors })) + if (rpcCors) app.use(cors({ origin: rpcCors })) app.use(jsonParser()) if (withEngineMiddleware) { @@ -57,15 +58,15 @@ export function createRPCServerListener(opts: CreateRPCServerListenerOpts): Http export function createWsRPCServerListener( opts: CreateRPCServerListenerOpts & { httpServer?: HttpServer } ): HttpServer | undefined { - const { server, withEngineMiddleware } = opts - // Get the server to hookup upgrade request on + const { server, withEngineMiddleware, rpcCors } = opts + // Get the server to hookup upgrade request on let httpServer = opts.httpServer if (!httpServer) { const app = Connect() - // Incase browser pre-flights the upgrade request with an options request + // In case browser pre-flights the upgrade request with an options request // more likely in case of wss connection - if (opts.rpcCors) app.use(cors({ origin: opts.rpcCors })) + if (rpcCors) app.use(cors({ origin: rpcCors })) httpServer = createServer(app) }