Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions packages/apify/src/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,10 @@ export class Actor<Data extends Dictionary = Dictionary> {
* ```
* { useApifyProxy: false }
* ```
*
* As part of the init process, we verify the configuration by checking the proxy status endpoint.
* This can make the init slower, to opt-out of this, use `checkAccess: false` (defaults to `true`).
*
* @ignore
*/
async createProxyConfiguration(
Expand All @@ -1383,7 +1387,8 @@ export class Actor<Data extends Dictionary = Dictionary> {
): Promise<ProxyConfiguration | undefined> {
// Compatibility fix for Input UI where proxy: None returns { useApifyProxy: false }
// Without this, it would cause proxy to use the zero config / auto mode.
const { useApifyProxy, ...options } = proxyConfigurationOptions;
const { useApifyProxy, checkAccess, ...options } =
proxyConfigurationOptions;
const dontUseApifyProxy = useApifyProxy === false;
const dontUseCustomProxies = !proxyConfigurationOptions.proxyUrls;

Expand All @@ -1393,7 +1398,7 @@ export class Actor<Data extends Dictionary = Dictionary> {

const proxyConfiguration = new ProxyConfiguration(options, this.config);

if (await proxyConfiguration.initialize()) {
if (await proxyConfiguration.initialize({ checkAccess })) {
return proxyConfiguration;
}

Expand Down Expand Up @@ -2183,6 +2188,9 @@ export class Actor<Data extends Dictionary = Dictionary> {
* ```
* { useApifyProxy: false }
* ```
*
* As part of the init process, we verify the configuration by checking the proxy status endpoint.
* This can make the init slower, to opt-out of this, use `checkAccess: false` (defaults to `true`).
*/
static async createProxyConfiguration(
proxyConfigurationOptions: ProxyConfigurationOptions & {
Expand Down
15 changes: 13 additions & 2 deletions packages/apify/src/proxy_configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ export interface ProxyConfigurationOptions
ProxyConfigurationOptions,
keyof CoreProxyConfigurationOptions | 'tieredProxyConfig'
>[];

/**
* As part of the init process, we verify the configuration by checking the proxy status endpoint.
* This can make the init slower, to opt-out of this, use `checkAccess: false` (defaults to `true`).
*/
checkAccess?: boolean;
}

/**
Expand Down Expand Up @@ -256,8 +262,11 @@ export class ProxyConfiguration extends CoreProxyConfiguration {
*
* You should use the {@apilink createProxyConfiguration} function to create a pre-initialized
* `ProxyConfiguration` instance instead of calling this manually.
*
* As part of the init process, we verify the configuration by checking the proxy status endpoint.
* This can make the init slower, to opt-out of this, use `checkAccess: false`.
*/
async initialize(): Promise<boolean> {
async initialize(options?: { checkAccess?: boolean }): Promise<boolean> {
if (this.usesApifyProxy) {
if (!this.password) {
await this._setPasswordIfToken();
Expand All @@ -280,7 +289,9 @@ export class ProxyConfiguration extends CoreProxyConfiguration {
}
}

return this._checkAccess();
if (options?.checkAccess !== false) {
return this._checkAccess();
}
}

return true;
Expand Down
37 changes: 37 additions & 0 deletions test/apify/proxy_configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,11 @@ describe('Actor.createProxyConfiguration()', () => {
const proxyUrl = proxyUrlNoSession;
const url = 'http://proxy.apify.com/?format=json';
gotScrapingSpy.mockResolvedValueOnce({ body: status } as any);
const checkAccessSpy = vitest.spyOn(
ProxyConfiguration.prototype,
// @ts-ignore protected method
'_checkAccess',
);

const proxyConfiguration =
await Actor.createProxyConfiguration(basicOpts);
Expand All @@ -582,6 +587,7 @@ describe('Actor.createProxyConfiguration()', () => {
expect(proxyConfiguration.hostname).toBe(hostname);
// @ts-expect-error private property
expect(proxyConfiguration.port).toBe(port);
expect(checkAccessSpy).toHaveBeenCalled();

expect(gotScrapingSpy).toBeCalledWith({
url,
Expand All @@ -591,6 +597,37 @@ describe('Actor.createProxyConfiguration()', () => {
});
});

test('disabling `checkAccess`', async () => {
const status = { connected: true };
const proxyUrl = proxyUrlNoSession;
const url = 'http://proxy.apify.com/?format=json';
gotScrapingSpy.mockResolvedValueOnce({ body: status } as any);
const checkAccessSpy = vitest.spyOn(
ProxyConfiguration.prototype,
// @ts-ignore protected method
'_checkAccess',
);

const proxyConfiguration = await Actor.createProxyConfiguration({
...basicOpts,
checkAccess: false,
});

expect(proxyConfiguration).toBeInstanceOf(ProxyConfiguration);
// @ts-expect-error private property
expect(proxyConfiguration.groups).toBe(groups);
// @ts-expect-error private property
expect(proxyConfiguration.countryCode).toBe(countryCode);
// @ts-expect-error private property
expect(proxyConfiguration.password).toBe(password);
// @ts-expect-error private property
expect(proxyConfiguration.hostname).toBe(hostname);
// @ts-expect-error private property
expect(proxyConfiguration.port).toBe(port);
expect(checkAccessSpy).not.toHaveBeenCalled();
expect(gotScrapingSpy).not.toHaveBeenCalled();
});

test('should work without password (with token)', async () => {
process.env.APIFY_TOKEN = '123456789';
const opts: Dictionary = { ...basicOpts };
Expand Down
Loading