Skip to content

Conversation

@bliuchak
Copy link
Contributor

@bliuchak bliuchak commented Dec 2, 2025

This PR represents simplification of #602. It contains changes related only to HTTPS proxy server support.

Scope:

  • https proxy server + backward compatibility

Out Of Scope (should be fixed separately):

  • TLS overhead. It's not included in connection statistic.
  • HTTPS upstream proxy. By default they should work out of the box, however we're missing test coverage for them. Also TLS overhead is not included in connection statistic when HTTPS upstream proxy is used.
  • IPv6 tests with HTTPS proxy. In general IPv6 with HTTPS proxy should work with no issue, however I can't proof it in tests due to limitation of got-scrapting.

Note: I might miss some edge cases for HTTPS server proxy, however I think that current coverage is good enough and covers core logic fully (80/20) and is backward compatible (HTTP proxy server tests pass).

@github-actions github-actions bot added t-core-services Issues with this label are in the ownership of the core services team. tested Temporary label used only programatically for some analytics. labels Dec 2, 2025
@bliuchak bliuchak added medium priority Medium priority issues to be done in a couple of sprints. t-unblocking Issues with this label are in the ownership of the unblocking team. labels Dec 2, 2025
Copy link
Member

@jirimoravcik jirimoravcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, looks great, had a few comments

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(opt) This file would benefit from a split into multiple ones.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you already have https-stress-test.js, so maybe the new nice https scenarios could be stand-alone files as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, I'll take a look at it.

Copy link

@tobice tobice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I have no idea how proxy-chain works and my general knowledge of proxies is still limited 😄 So I'm leaving the actual functionality review to Jirka and Ludvík.

From my PoV the application code change is small, well documented and easy to read. No concerns there.

The tests, especially the new ones, would benefit from splitting into files. Also one scenario caught my attention due to its nested structure. I'm not sure why that's needed.

Finally, I'd expand on the PR description. You can e.g. add there the nice diagram from the original PR.

* Connection statistics for bandwidth tracking.
*/
export type ConnectionStats = {
// Bytes sent from proxy to client.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by these descriptions. Is this one even correct? Shouldn't it be from client to proxy?

Also Bytes received from client to proxy. is not very good English, which further complicates the readability.

I'd do:

  • Bytes sent by client to proxy
  • Bytes received by proxy from client

This should be clear and unambiguous.

}

// Apply secure TLS defaults (user options can override).
const secureDefaults: https.ServerOptions = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const secureDefaults: https.ServerOptions = {
const effectiveOptions: https.ServerOptions = {

(nit) IMHO these are no longer defaults.

const DEFAULT_AUTH_REALM = 'ProxyChain';
const DEFAULT_PROXY_SERVER_PORT = 8000;

const HTTPS_DEFAULTS = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const HTTPS_DEFAULTS = {
const HTTPS_DEFAULT_OPTIONS = {

(opt) Just more consistent naming across the code...

if (this.serverType === 'https') {
// For HTTPS: Track only post-TLS-handshake sockets (secureConnection).
// This ensures we track the TLS-wrapped socket with correct bytesRead/bytesWritten.
this.server.on('secureConnection', this.onConnection.bind(this));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the server is HTTPs but somebody tries to establish an insecure connection? Is that even possible? 🤔


// Not specific for https but still worth to have.
it('handles 100 concurrent CONNECT tunnels with data verification', async () => {
const TUNNELS = 100;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const TUNNELS = 100;
const TUNNEL_COUNT = 100;

(opt)(nit)

Dtto below for REQUESTS.

}
});

it('handles TLS handshake failures gracefully and continues accepting connections', function (done) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(opt) The describe has only one it. Maybe you can inline it?

tlsErrors.push(error);
});

server.listen().then(() => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make the test async and then do await server.listen()? 🤔 In general the structure of this test is super weird and confusing with all the nesting and relying on done.

Maybe you can promisify the socket communication instead to keep the structure more flat?

await server.listen();

const badSocked = tls.connect({ ... });

await new Promise((resolve) => badSocket.on('close', resolve));
await promiseDelay(1000); // We have utility like this somewhere

(I can see you are doing that below.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you already have https-stress-test.js, so maybe the new nice https scenarios could be stand-alone files as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

medium priority Medium priority issues to be done in a couple of sprints. t-core-services Issues with this label are in the ownership of the core services team. t-unblocking Issues with this label are in the ownership of the unblocking team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants