From 82c44f43202b54135bae2d1090d747372232e9ef Mon Sep 17 00:00:00 2001 From: Andreas Zeissner Date: Mon, 26 Aug 2024 22:09:41 +0200 Subject: [PATCH] feat: enable proxy handling for native fetch and connectrpc calls Setting the proxy relies on undici for now undici does not respect the HTTP_PROXY vars, it's planned to build it in from v23 on by default: https://github.com/nodejs/node/issues/43187#issuecomment-2090243675 > My current plan is to add support for the HTTP_PROXY env variable behind a flag in v22 (and possibly v20), then unflag in v23. Using global dispatcher is the current way to go for native fetch, therefore undici needs to be added. For connectrpc the agent will be passed down the chain: /** * Options passed to the request() call of the Node.js built-in * http or https module. * example proxy trace: 22:05:23 HTTPS POST localhost/auth/realms/cosmo/protocol/openid-connect/token 200 application/json 2.0k 202ms 22:05:35 HTTP POST localhost/wg.cosmo.platform.v1.PlatformService/DeleteFederatedGraph 200 application/proto 44b 64ms --- cli/package.json | 3 ++- cli/src/commands/index.ts | 14 ++++++++++++++ cli/src/core/client/client.ts | 6 +++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cli/package.json b/cli/package.json index 4b6beea3d5..d08352d9ed 100644 --- a/cli/package.json +++ b/cli/package.json @@ -59,7 +59,8 @@ "open": "^9.1.0", "ora": "^8.0.1", "pathe": "^1.1.1", - "picocolors": "^1.0.0" + "picocolors": "^1.0.0", + "undici": "^6.19.8" }, "devDependencies": { "@types/cli-progress": "^3.11.5", diff --git a/cli/src/commands/index.ts b/cli/src/commands/index.ts index 32fe52b881..354da05551 100644 --- a/cli/src/commands/index.ts +++ b/cli/src/commands/index.ts @@ -14,9 +14,23 @@ import ContractCommands from './contract/index.js'; import FeatureGraphCommands from './feature-subgraph/index.js'; import FeatureFlagCommands from './feature-flag/index.js'; +const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; + +if (proxyUrl) { + // Lazy load undici only when needed + const { setGlobalDispatcher, ProxyAgent } = await import('undici'); + + // Set the global dispatcher for undici to route through the proxy + const dispatcher = new ProxyAgent({ + uri: new URL(proxyUrl).toString(), + }); + setGlobalDispatcher(dispatcher); +} + const client = CreateClient({ baseUrl: config.baseURL, apiKey: config.apiKey, + proxyUrl, }); const program = new Command(); diff --git a/cli/src/core/client/client.ts b/cli/src/core/client/client.ts index d55d82e323..b148a635b9 100644 --- a/cli/src/core/client/client.ts +++ b/cli/src/core/client/client.ts @@ -2,10 +2,12 @@ import { compressionBrotli, compressionGzip, createConnectTransport } from '@con import { createPromiseClient, PromiseClient } from '@connectrpc/connect'; import { PlatformService } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_connect'; import { NodeService } from '@wundergraph/cosmo-connect/dist/node/v1/node_connect'; +import { HttpsProxyAgent } from 'https-proxy-agent'; export interface ClientOptions { baseUrl: string; apiKey?: string; + proxyUrl?: string; } export interface Client { @@ -20,7 +22,9 @@ export const CreateClient = (opts: ClientOptions): Client => { // You have to tell the Node.js http API which HTTP version to use. httpVersion: '1.1', - + nodeOptions: { + agent: opts.proxyUrl ? new HttpsProxyAgent(opts.proxyUrl) : undefined, + }, // Avoid compression for small requests compressMinBytes: 1024,