feat: support socks proxy in Fetch API (#9545)

This commit is contained in:
Andrey Lushnikov 2021-10-15 11:33:21 -07:00 committed by GitHub
parent b383c6bf3c
commit 7a187d9994
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 3 deletions

71
package-lock.json generated
View file

@ -5073,6 +5073,11 @@
"node": ">= 0.10"
}
},
"node_modules/ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"node_modules/ip-regex": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
@ -7818,6 +7823,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@ -7960,6 +7974,32 @@
"dev": true,
"optional": true
},
"node_modules/socks": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
"integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
"dependencies": {
"ip": "^1.1.5",
"smart-buffer": "^4.1.0"
},
"engines": {
"node": ">= 10.13.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks-proxy-agent": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz",
"integrity": "sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg==",
"dependencies": {
"agent-base": "^6.0.2",
"debug": "^4.3.1",
"socks": "^2.6.1"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/socksv5": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/socksv5/-/socksv5-0.0.6.tgz",
@ -9304,6 +9344,7 @@
"proper-lockfile": "^4.1.1",
"proxy-from-env": "^1.1.0",
"rimraf": "^3.0.2",
"socks-proxy-agent": "^6.1.0",
"stack-utils": "^2.0.3",
"ws": "^7.4.6",
"yauzl": "^2.10.0",
@ -13257,6 +13298,11 @@
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"dev": true
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"ip-regex": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
@ -14687,6 +14733,7 @@
"proper-lockfile": "^4.1.1",
"proxy-from-env": "^1.1.0",
"rimraf": "^3.0.2",
"socks-proxy-agent": "^6.1.0",
"stack-utils": "^2.0.3",
"ws": "^7.4.6",
"yauzl": "^2.10.0",
@ -15384,6 +15431,11 @@
}
}
},
"smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
},
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@ -15505,6 +15557,25 @@
"kind-of": "^3.2.0"
}
},
"socks": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
"integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
"requires": {
"ip": "^1.1.5",
"smart-buffer": "^4.1.0"
}
},
"socks-proxy-agent": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz",
"integrity": "sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg==",
"requires": {
"agent-base": "^6.0.2",
"debug": "^4.3.1",
"socks": "^2.6.1"
}
},
"socksv5": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/socksv5/-/socksv5-0.0.6.tgz",

View file

@ -38,6 +38,7 @@
"proper-lockfile": "^4.1.1",
"proxy-from-env": "^1.1.0",
"rimraf": "^3.0.2",
"socks-proxy-agent": "^6.1.0",
"stack-utils": "^2.0.3",
"ws": "^7.4.6",
"yauzl": "^2.10.0",

View file

@ -17,6 +17,7 @@
import * as http from 'http';
import * as https from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { SocksProxyAgent } from 'socks-proxy-agent';
import { pipeline, Readable, Transform } from 'stream';
import url from 'url';
import zlib from 'zlib';
@ -108,10 +109,17 @@ export abstract class FetchRequest extends SdkObject {
if (proxy) {
// TODO: support bypass proxy
const proxyOpts = url.parse(proxy.server);
if (proxyOpts.protocol?.startsWith('socks')) {
agent = new SocksProxyAgent({
host: proxyOpts.hostname,
port: proxyOpts.port || undefined,
});
} else {
if (proxy.username)
proxyOpts.auth = `${proxy.username}:${proxy.password || ''}`;
agent = new HttpsProxyAgent(proxyOpts);
}
}
const timeout = defaults.timeoutSettings.timeout(params);
const deadline = timeout && (monotonicTime() + timeout);

View file

@ -115,6 +115,14 @@ it('should return error with wrong credentials', async ({ playwright, server })
expect(response2.status()).toBe(401);
});
it('should use socks proxy', async ({ playwright, server, socksPort }) => {
const request = await playwright.request.newContext({ proxy: {
server: `socks5://localhost:${socksPort}`,
} });
const response = await request.get(server.EMPTY_PAGE);
expect(await response.text()).toContain('Served by the SOCKS proxy');
});
it('should pass proxy credentials', async ({ playwright, server, proxyServer }) => {
proxyServer.forwardTo(server.PORT);
let auth;