Skip to content

Conversation

@tducret
Copy link
Contributor

@tducret tducret commented Nov 19, 2025

Hello 👋

Here is a PR proposition to be able to use apify CLI in a sandboxed environment (in my case, Claude code in the browser).

At the moment, we can't do apify login or apify info in such environment, because the apify-client doesn't handle the proxy configuration properly.
The commands are stuck.

Digging into it, I found out that the agentkeepalive module doesn't support proxy (see node-modules/agentkeepalive#22 (comment) for instance).

I first attempted to use proxy-agents, but it turns out the built-in agents can support both keepalive and proxies out of the box.

So this PR removes agentkeepalive while maintaining the same keep-alive functionality and adding proxy support capability.

Test

To test it locally, I created a transparent proxy (we don't intercept requests to avoid self-certificate issues):

mitmdump --listen-port 8000 --ignore-hosts '.*:*' --set dns_log=true

And in another terminal, I tested the Apify client with :

export HTTPS_PROXY=http://localhost:8000
export APIFY_TOKEN=[REPLACE_WITH_VALID_TOKEN]

node get-user-info.js  # See code below
#!/usr/bin/env node

const { ApifyClient } = require('./dist/index.js');

async function main() {
    // Get token from environment variable
    const token = process.env.APIFY_TOKEN;

    if (!token) {
        console.error('Error: APIFY_TOKEN environment variable is not set');
        process.exit(1);
    }

    try {
        const client = new ApifyClient({ token });

        console.log('Fetching user information...\n');
        const userInfo = await client.user().get();

        console.log('User Information:');
        console.log(JSON.stringify(userInfo, null, 2));
    } catch (error) {
        console.error('Error fetching user information:');
        console.error(error.message);
        if (error.statusCode) {
            console.error(`Status Code: ${error.statusCode}`);
        }
        process.exit(1);
    }
}

main();

…y support

Replace the agentkeepalive dependency with Node.js native http.Agent and https.Agent to enable HTTP proxy support. The native agents support the HTTP_PROXY and HTTPS_PROXY environment variables out of the box, allowing the client to work seamlessly with proxy configurations.

This change maintains the same keep-alive functionality while removing an external dependency and adding proxy support capability.
@tducret
Copy link
Contributor Author

tducret commented Nov 20, 2025

Hi there! Not sure about the right way to get feedback.
Could you please take a look @janbuchar @Pijukatel @B4nan ?

@B4nan B4nan requested a review from Copilot November 20, 2025 07:17
Copilot finished reviewing on behalf of B4nan November 20, 2025 07:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR replaces the agentkeepalive library with native Node.js HTTP agents to enable proxy support in sandboxed environments. The agentkeepalive module doesn't support proxy configuration, which prevented the Apify CLI from working properly in environments like Claude Code in the browser.

  • Removes agentkeepalive dependency and uses built-in http.Agent and https.Agent instead
  • Maintains keep-alive functionality by explicitly setting keepAlive: true in agent options
  • Enables automatic proxy support via standard environment variables (HTTP_PROXY, HTTPS_PROXY)

Reviewed Changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/http_client.ts Replaced agentkeepalive imports with native node:http and node:https modules, updated agent instantiation to use native agents with keepAlive: true, and updated type annotations
package.json Removed agentkeepalive dependency from the dependencies list
package-lock.json Removed agentkeepalive and its transitive dependency humanize-ms, and correctly marked ms as a devDependency since it's only used by dev tools

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Pijukatel Pijukatel requested review from B4nan and janbuchar November 20, 2025 08:18
@B4nan B4nan requested review from barjin and removed request for B4nan November 20, 2025 09:42
// while waiting for the response.
const agentOpts = {
const agentOptions: http.AgentOptions = {
keepAlive: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not the only thing that agentkeepalive adds.

Image

...is it safe to ignore the rest of the changes they mention?

Copy link
Contributor Author

@tducret tducret Nov 20, 2025

Choose a reason for hiding this comment

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

Good point, I've just added commit c424e90 with these optimizations.

Improved native Node.js HTTP/HTTPS agent configuration with:
  - Disabled Nagle's algorithm (setNoDelay) for lower latency
  - LIFO socket scheduling to reuse warm connections
  - Free socket timeout (15s) to prevent connection leaks
  - Configurable socket pool limits (256 max sockets)
  - Better keepalive management with timeoutMillis
@tducret tducret force-pushed the feat/better-proxy-support branch from 02e5e04 to 4fd4403 Compare November 20, 2025 10:42
Copy link
Contributor

@janbuchar janbuchar left a comment

Choose a reason for hiding this comment

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

I think this is good to go, but let's give @barjin a chance to review it too. Thanks @tducret!

Copy link
Member

@barjin barjin left a comment

Choose a reason for hiding this comment

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

Thank you @tducret , please address my comment. Otherwise, it looks good to go to me!

A quick look at the traffic captures shows a similar TCP connection count / timings, so these changes should be safe 👍

Comment on lines +1 to +2
import http from 'node:http';
import https from 'node:https';
Copy link
Member

Choose a reason for hiding this comment

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

Can you please add both these modules as externals to rsbuild.config.ts (link)? They are not used outside of Node, so we don't need them in the browser bundle. Together, they add around 250kB to the bundle size.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure thing, done in commit f986aa4

Copy link
Member

Choose a reason for hiding this comment

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

Thank you!

Add node:http and node:https to rsbuild externals configuration to prevent bundling these Node.js-only modules in the browser build, reducing bundle size by ~250kB.
@janbuchar janbuchar merged commit 7d2be0f into apify:master Nov 20, 2025
7 checks passed
@tducret
Copy link
Contributor Author

tducret commented Nov 20, 2025

Thanks for your reactivity ⚡
Is there anything I can do get this fix in the apify CLI?
Without it, I'm currently stuck in the Claude code cloud sandbox.

@janbuchar
Copy link
Contributor

Thanks for your reactivity ⚡ Is there anything I can do get this fix in the apify CLI? Without it, I'm currently stuck in the Claude code cloud sandbox.

I'm going to release the updated apify-client-js now. Then it depends on how you installed the CLI. If you use the global npm install method, you should be able to just update your global apify-client version to the new one.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants