From cf26fdb08857bbb9e04365ab0b0c67cbba435bcf Mon Sep 17 00:00:00 2001 From: dmkozin Date: Wed, 21 Jan 2026 12:56:16 +0300 Subject: [PATCH 1/2] Add upstreamproxy flag --- package.json | 3 +++ src/interfaces.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/package.json b/package.json index d68f465..ff4252c 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,9 @@ }, "blacklisteddomains": { "type": "string" + }, + "upstreamproxy": { + "type": "string" } }, "title": "Appium interceptor plugin", diff --git a/src/interfaces.ts b/src/interfaces.ts index 55e7020..6a16c9b 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -4,10 +4,12 @@ export interface IPluginArgs { certdirectory: string; whitelisteddomains: string[] | string; blacklisteddomains: string[] | string; + upstreamproxy: string | null; } export const DefaultPluginArgs: IPluginArgs = { certdirectory: path.join(__dirname, '..', 'certificate'), whitelisteddomains: [], blacklisteddomains: [], + upstreamproxy: null, }; \ No newline at end of file From 0077a43ff3554c9b790c24bd6bbe538bfe904042 Mon Sep 17 00:00:00 2001 From: dmkozin Date: Wed, 21 Jan 2026 18:01:03 +0300 Subject: [PATCH 2/2] Upstream proxy from cli args --- README.md | 6 ++++++ docs/commands.md | 6 +++++- src/plugin.ts | 6 ++++++ src/proxy.ts | 7 ++++--- src/utils/proxy.ts | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 38204ae..bf6bcb2 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,12 @@ Example of `blacklisteddomains`: all the calls go through the proxy, except the Note: `whitelisteddomains` and `blacklisteddomains` are two different approach and are not supposed to be used together. If both are present, `blacklisteddomains` will be ignored. +#### 👉 Upstream proxy + +To forward all intercepted traffic through another proxy, start Appium with the `upstreamproxy` argument: + +`appium server -ka 800 --use-plugins=appium-interceptor --plugin-appium-interceptor-upstreamproxy="http://proxy-host:3128" -pa /wd/hub` + ### Capabilities To control the plugin behavior, you can use the following capabilities: diff --git a/docs/commands.md b/docs/commands.md index efd79b6..9d22d2f 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -8,7 +8,11 @@ To enable network interception, configure your Appium session using the `appium: 👉 Once the proxy is successfully started (either automatically or manually), you can manage API mocking, recording, and sniffing using the commands detailed below. -To route emulator traffic through another proxy, set one of the environment variables UPSTREAM_PROXY, HTTPS_PROXY, or HTTP_PROXY. All traffic from the emulator will then be forwarded to the specified upstream proxy. +To route emulator traffic through another proxy, pass the Appium plugin argument `upstreamproxy` when starting the server, for example: + +`appium server -ka 800 --use-plugins=appium-interceptor --plugin-appium-interceptor-upstreamproxy="http://proxy-host:3128" -pa /wd/hub` + +All traffic from the emulator will then be forwarded to the specified upstream proxy. ### Mock Configuration Mock configuration is a json object that defines the specification for filtering and applying various updates to the api request and below is the structure for the config object. diff --git a/src/plugin.ts b/src/plugin.ts index 3eff099..4a54e06 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -282,6 +282,11 @@ export class AppiumInterceptorPlugin extends BasePlugin { ? this.pluginArgs.blacklisteddomains : parseJson(this.pluginArgs.blacklisteddomains), ); + const upstreamProxy = + typeof this.pluginArgs.upstreamproxy === 'string' && + this.pluginArgs.upstreamproxy.trim().length > 0 + ? this.pluginArgs.upstreamproxy.trim() + : null; const proxy = await setupProxyServer( sessionId, deviceUDID, @@ -290,6 +295,7 @@ export class AppiumInterceptorPlugin extends BasePlugin { currentGlobalProxy, whitelistedDomains, blacklistedDomains, + upstreamProxy, ); await configureWifiProxy(adb, deviceUDID, realDevice, proxy.options); diff --git a/src/proxy.ts b/src/proxy.ts index 9613991..c585b2c 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -30,6 +30,7 @@ export interface ProxyOptions { certificatePath: string; port: number; ip: string; + upstreamProxy?: string | null; previousConfig?: ProxyOptions; whitelistedDomains?: string[]; blacklistedDomains?: string[]; @@ -271,15 +272,15 @@ export class Proxy { } private async setupProxyChainUpstream(): Promise { - const upstreamEnv = process.env.UPSTREAM_PROXY || process.env.HTTPS_PROXY || process.env.HTTP_PROXY; - if (!upstreamEnv) return; + const upstreamProxy = this.options.upstreamProxy?.toString().trim(); + if (!upstreamProxy) return; try { const proxyChain = require('proxy-chain'); if (!proxyChain || !proxyChain.anonymizeProxy) { log.warn('proxy-chain not available; skipping upstream setup'); return; } - const localUrl: string = await proxyChain.anonymizeProxy(upstreamEnv); + const localUrl: string = await proxyChain.anonymizeProxy(upstreamProxy); this.proxyChainLocalUrl = localUrl; this.closeProxyChain = proxyChain.closeAnonymizedProxy; this.upstreamAgent = new ProxyAgent({ getProxyForUrl: () => localUrl }); diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts index c979bf8..cf9c3c9 100644 --- a/src/utils/proxy.ts +++ b/src/utils/proxy.ts @@ -115,12 +115,23 @@ export async function setupProxyServer( certDirectory: string, currentWifiProxyConfig?: ProxyOptions, whitelistedDomains?: string[], - blacklistedDomains?: string[] + blacklistedDomains?: string[], + upstreamProxy?: string | null, ) { const certificatePath = prepareCertificate(sessionId, certDirectory); const port = await getPort(); const _ip = isRealDevice ? 'localhost' : ip.address('public', 'ipv4'); - const proxy = new Proxy({ deviceUDID, sessionId, certificatePath, port, ip: _ip, previousConfig: currentWifiProxyConfig, whitelistedDomains, blacklistedDomains}); + const proxy = new Proxy({ + deviceUDID, + sessionId, + certificatePath, + port, + ip: _ip, + previousConfig: currentWifiProxyConfig, + whitelistedDomains, + blacklistedDomains, + upstreamProxy: upstreamProxy ?? null, + }); await proxy.start(); if (!proxy.isStarted()) { throw new Error('Unable to start the proxy server');