mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-27 21:58:52 +03:00
feat(proxy): bind proxy to open port (#8331)
This commit is contained in:
parent
70eca0401d
commit
80dded6ccf
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import net from 'net';
|
||||
import net, { AddressInfo } from 'net';
|
||||
import * as channels from '../protocol/channels';
|
||||
import { Playwright } from '../server/playwright';
|
||||
import { AndroidDispatcher } from './androidDispatcher';
|
||||
@ -25,6 +25,7 @@ import { SelectorsDispatcher } from './selectorsDispatcher';
|
||||
import * as types from '../server/types';
|
||||
import { SocksConnection, SocksConnectionClient } from '../utils/socksProxy';
|
||||
import { createGuid } from '../utils/utils';
|
||||
import { debugLogger } from '../utils/debugLogger';
|
||||
|
||||
export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.PlaywrightInitializer> implements channels.PlaywrightChannel {
|
||||
private _socksProxy: SocksProxy | undefined;
|
||||
@ -45,9 +46,10 @@ export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.Playwr
|
||||
}, false);
|
||||
}
|
||||
|
||||
enableSocksProxy(port: number) {
|
||||
async enableSocksProxy() {
|
||||
this._socksProxy = new SocksProxy(this);
|
||||
this._socksProxy.listen(port);
|
||||
this._object.options.socksProxyPort = await this._socksProxy.listen(0);
|
||||
debugLogger.log('proxy', `Starting socks proxy server on port ${this._object.options.socksProxyPort}`);
|
||||
}
|
||||
|
||||
async socksConnected(params: channels.PlaywrightSocksConnectedParams, metadata?: channels.Metadata): Promise<void> {
|
||||
@ -85,8 +87,12 @@ class SocksProxy implements SocksConnectionClient {
|
||||
});
|
||||
}
|
||||
|
||||
listen(port: number) {
|
||||
this._server.listen(port);
|
||||
async listen(port: number): Promise<number> {
|
||||
return new Promise(f => {
|
||||
this._server.listen(port, () => {
|
||||
f((this._server.address() as AddressInfo).port);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onSocketRequested(uid: string, host: string, port: number): void {
|
||||
|
@ -50,7 +50,7 @@ export class PlaywrightServer {
|
||||
playwright = createPlaywright();
|
||||
const dispatcher = new PlaywrightDispatcher(rootScope, playwright);
|
||||
if (process.env.PW_SOCKS_PROXY_PORT)
|
||||
dispatcher.enableSocksProxy(+process.env.PW_SOCKS_PROXY_PORT);
|
||||
await dispatcher.enableSocksProxy();
|
||||
return dispatcher;
|
||||
});
|
||||
return () => {
|
||||
|
@ -33,8 +33,9 @@ export interface BrowserProcess {
|
||||
}
|
||||
|
||||
export type PlaywrightOptions = {
|
||||
rootSdkObject: SdkObject,
|
||||
selectors: Selectors,
|
||||
rootSdkObject: SdkObject;
|
||||
selectors: Selectors;
|
||||
socksProxyPort?: number;
|
||||
};
|
||||
|
||||
export type BrowserOptions = PlaywrightOptions & {
|
||||
|
@ -53,7 +53,7 @@ export abstract class BrowserType extends SdkObject {
|
||||
}
|
||||
|
||||
async launch(metadata: CallMetadata, options: types.LaunchOptions, protocolLogger?: types.ProtocolLogger): Promise<Browser> {
|
||||
options = validateLaunchOptions(options);
|
||||
options = this._validateLaunchOptions(options);
|
||||
const controller = new ProgressController(metadata, this);
|
||||
controller.setLogName('browser');
|
||||
const browser = await controller.run(progress => {
|
||||
@ -63,7 +63,7 @@ export abstract class BrowserType extends SdkObject {
|
||||
}
|
||||
|
||||
async launchPersistentContext(metadata: CallMetadata, userDataDir: string, options: types.LaunchPersistentOptions): Promise<BrowserContext> {
|
||||
options = validateLaunchOptions(options);
|
||||
options = this._validateLaunchOptions(options);
|
||||
const controller = new ProgressController(metadata, this);
|
||||
const persistent: types.BrowserContextOptions = options;
|
||||
controller.setLogName('browser');
|
||||
@ -243,6 +243,18 @@ export abstract class BrowserType extends SdkObject {
|
||||
throw new Error('CDP connections are only supported by Chromium');
|
||||
}
|
||||
|
||||
private _validateLaunchOptions<Options extends types.LaunchOptions>(options: Options): Options {
|
||||
const { devtools = false } = options;
|
||||
let { headless = !devtools, downloadsPath, proxy } = options;
|
||||
if (debugMode())
|
||||
headless = false;
|
||||
if (downloadsPath && !path.isAbsolute(downloadsPath))
|
||||
downloadsPath = path.join(process.cwd(), downloadsPath);
|
||||
if (this._playwrightOptions.socksProxyPort)
|
||||
proxy = { server: `socks5://127.0.0.1:${this._playwrightOptions.socksProxyPort}` };
|
||||
return { ...options, devtools, headless, downloadsPath, proxy };
|
||||
}
|
||||
|
||||
abstract _defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[];
|
||||
abstract _connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise<Browser>;
|
||||
abstract _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env;
|
||||
@ -256,15 +268,3 @@ function copyTestHooks(from: object, to: object) {
|
||||
(to as any)[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function validateLaunchOptions<Options extends types.LaunchOptions>(options: Options): Options {
|
||||
const { devtools = false } = options;
|
||||
let { headless = !devtools, downloadsPath, proxy } = options;
|
||||
if (debugMode())
|
||||
headless = false;
|
||||
if (downloadsPath && !path.isAbsolute(downloadsPath))
|
||||
downloadsPath = path.join(process.cwd(), downloadsPath);
|
||||
if (process.env.PW_SOCKS_PROXY_PORT)
|
||||
proxy = { server: `socks5://127.0.0.1:${process.env.PW_SOCKS_PROXY_PORT}` };
|
||||
return { ...options, devtools, headless, downloadsPath, proxy };
|
||||
}
|
||||
|
@ -163,14 +163,14 @@ export class Chromium extends BrowserType {
|
||||
const proxyURL = new URL(proxy.server);
|
||||
const isSocks = proxyURL.protocol === 'socks5:';
|
||||
// https://www.chromium.org/developers/design-documents/network-settings
|
||||
if (isSocks && !process.env.PW_SOCKS_PROXY_PORT) {
|
||||
if (isSocks && !this._playwrightOptions.socksProxyPort) {
|
||||
// https://www.chromium.org/developers/design-documents/network-stack/socks-proxy
|
||||
chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
|
||||
}
|
||||
chromeArguments.push(`--proxy-server=${proxy.server}`);
|
||||
const proxyBypassRules = [];
|
||||
// https://source.chromium.org/chromium/chromium/src/+/master:net/docs/proxy.md;l=548;drc=71698e610121078e0d1a811054dcf9fd89b49578
|
||||
if (process.env.PW_SOCKS_PROXY_PORT)
|
||||
if (this._playwrightOptions.socksProxyPort)
|
||||
proxyBypassRules.push('<-loopback>');
|
||||
if (proxy.bypass)
|
||||
proxyBypassRules.push(...proxy.bypass.split(',').map(t => t.trim()).map(t => t.startsWith('.') ? '*' + t : t));
|
||||
|
@ -33,7 +33,7 @@ class OutOfProcessPlaywrightServer {
|
||||
detached: true,
|
||||
env: {
|
||||
...process.env,
|
||||
PW_SOCKS_PROXY_PORT: String(proxyPort)
|
||||
PW_SOCKS_PROXY_PORT: '1'
|
||||
}
|
||||
});
|
||||
this._driverProcess.unref();
|
||||
@ -44,6 +44,9 @@ class OutOfProcessPlaywrightServer {
|
||||
if (line.startsWith(prefix))
|
||||
resolve(line.substr(prefix.length));
|
||||
});
|
||||
this._driverProcess.stderr.on('data', (data: Buffer) => {
|
||||
console.log(data.toString());
|
||||
});
|
||||
this._driverProcess.on('exit', () => reject());
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user