Skip to content

Commit

Permalink
https support for proxy relay (#564)
Browse files Browse the repository at this point in the history
Fix for issue #563 

---------

Co-authored-by: Jiří Moravčík <[email protected]>
  • Loading branch information
arenevier and jirimoravcik authored Dec 2, 2024
1 parent 84ef1c8 commit be4bf40
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/chain.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import http from 'http';
import https from 'https';
import dns from 'dns';
import { URL } from 'url';
import { EventEmitter } from 'events';
Expand Down Expand Up @@ -80,7 +81,8 @@ export const chain = (
options.headers.push('proxy-authorization', getBasicAuthorizationHeader(proxy));
}

const client = http.request(proxy.origin, options as unknown as http.ClientRequestArgs);
const fn = proxy.protocol === 'https:' ? https.request : http.request;
const client = fn(proxy.origin, options as unknown as http.ClientRequestArgs);

client.on('connect', (response, targetSocket, clientHead) => {
countTargetBytes(sourceSocket, targetSocket);
Expand Down
4 changes: 2 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,9 @@ export class Server extends EventEmitter {
throw new Error(`Invalid "upstreamProxyUrl" provided: ${error} (was "${funcResult.upstreamProxyUrl}"`);
}

if (!['http:', ...SOCKS_PROTOCOLS].includes(handlerOpts.upstreamProxyUrlParsed.protocol)) {
if (!['http:', 'https:', ...SOCKS_PROTOCOLS].includes(handlerOpts.upstreamProxyUrlParsed.protocol)) {
// eslint-disable-next-line max-len
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}")`);
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}")`);
}
}

Expand Down
40 changes: 40 additions & 0 deletions test/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const util = require('util');
const { expect, assert } = require('chai');
const proxy = require('proxy');
const http = require('http');
const https = require('https');
const portastic = require('portastic');
const request = require('request');
const WebSocket = require('faye-websocket');
Expand Down Expand Up @@ -1337,6 +1338,45 @@ it('supports localAddress', async () => {
}
});

it('supports https proxy relay', async () => {
const target = https.createServer(() => {
});
target.listen(() => {
});

const proxyServer = new ProxyChain.Server({
port: 6666,
prepareRequestFunction: () => {
console.log(`https://localhost:${target.address().port}`);
return {
upstreamProxyUrl: `https://localhost:${target.address().port}`,
};
},
});
let proxyServerError = false;
proxyServer.on('requestFailed', () => {
// requestFailed will be called if we pass an invalid proxy url
proxyServerError = true;
})

await proxyServer.listen();

try {
await requestPromised({
url: 'https://www.google.com',
proxy: 'http://localhost:6666',
strictSSL: false,
});
} catch (e) {
// the request will fail with the following error:
// Error: tunneling socket could not be established, statusCode=599
}
expect(proxyServerError).to.be.equal(false);

proxyServer.close();
target.close();
});

it('supports custom CONNECT server handler', async () => {
const server = new Server({
port: 0,
Expand Down

0 comments on commit be4bf40

Please sign in to comment.