Skip to content

Commit be4bf40

Browse files
https support for proxy relay (#564)
Fix for issue #563 --------- Co-authored-by: Jiří Moravčík <[email protected]>
1 parent 84ef1c8 commit be4bf40

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

src/chain.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import http from 'http';
2+
import https from 'https';
23
import dns from 'dns';
34
import { URL } from 'url';
45
import { EventEmitter } from 'events';
@@ -80,7 +81,8 @@ export const chain = (
8081
options.headers.push('proxy-authorization', getBasicAuthorizationHeader(proxy));
8182
}
8283

83-
const client = http.request(proxy.origin, options as unknown as http.ClientRequestArgs);
84+
const fn = proxy.protocol === 'https:' ? https.request : http.request;
85+
const client = fn(proxy.origin, options as unknown as http.ClientRequestArgs);
8486

8587
client.on('connect', (response, targetSocket, clientHead) => {
8688
countTargetBytes(sourceSocket, targetSocket);

src/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,9 @@ export class Server extends EventEmitter {
453453
throw new Error(`Invalid "upstreamProxyUrl" provided: ${error} (was "${funcResult.upstreamProxyUrl}"`);
454454
}
455455

456-
if (!['http:', ...SOCKS_PROTOCOLS].includes(handlerOpts.upstreamProxyUrlParsed.protocol)) {
456+
if (!['http:', 'https:', ...SOCKS_PROTOCOLS].includes(handlerOpts.upstreamProxyUrlParsed.protocol)) {
457457
// eslint-disable-next-line max-len
458-
throw new Error(`Invalid "upstreamProxyUrl" provided: URL must have one of the following protocols: "http", ${SOCKS_PROTOCOLS.map((p) => `"${p.replace(':', '')}"`).join(', ')} (was "${funcResult.upstreamProxyUrl}")`);
458+
throw new Error(`Invalid "upstreamProxyUrl" provided: URL must have one of the following protocols: "http", "https", ${SOCKS_PROTOCOLS.map((p) => `"${p.replace(':', '')}"`).join(', ')} (was "${funcResult.upstreamProxyUrl}")`);
459459
}
460460
}
461461

test/server.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const util = require('util');
99
const { expect, assert } = require('chai');
1010
const proxy = require('proxy');
1111
const http = require('http');
12+
const https = require('https');
1213
const portastic = require('portastic');
1314
const request = require('request');
1415
const WebSocket = require('faye-websocket');
@@ -1337,6 +1338,45 @@ it('supports localAddress', async () => {
13371338
}
13381339
});
13391340

1341+
it('supports https proxy relay', async () => {
1342+
const target = https.createServer(() => {
1343+
});
1344+
target.listen(() => {
1345+
});
1346+
1347+
const proxyServer = new ProxyChain.Server({
1348+
port: 6666,
1349+
prepareRequestFunction: () => {
1350+
console.log(`https://localhost:${target.address().port}`);
1351+
return {
1352+
upstreamProxyUrl: `https://localhost:${target.address().port}`,
1353+
};
1354+
},
1355+
});
1356+
let proxyServerError = false;
1357+
proxyServer.on('requestFailed', () => {
1358+
// requestFailed will be called if we pass an invalid proxy url
1359+
proxyServerError = true;
1360+
})
1361+
1362+
await proxyServer.listen();
1363+
1364+
try {
1365+
await requestPromised({
1366+
url: 'https://www.google.com',
1367+
proxy: 'http://localhost:6666',
1368+
strictSSL: false,
1369+
});
1370+
} catch (e) {
1371+
// the request will fail with the following error:
1372+
// Error: tunneling socket could not be established, statusCode=599
1373+
}
1374+
expect(proxyServerError).to.be.equal(false);
1375+
1376+
proxyServer.close();
1377+
target.close();
1378+
});
1379+
13401380
it('supports custom CONNECT server handler', async () => {
13411381
const server = new Server({
13421382
port: 0,

0 commit comments

Comments
 (0)