Lazy import proxy-agent
This commit is contained in:
parent
83e8f4b59d
commit
091b50c414
9 changed files with 60 additions and 39 deletions
|
@ -338,7 +338,7 @@ describe('updater/differential', () => {
|
|||
await assert.isRejected(
|
||||
download(outFile, data, {
|
||||
gotOptions: {
|
||||
...getGotOptions(),
|
||||
...(await getGotOptions()),
|
||||
timeout: {
|
||||
connect: 0.5 * durations.SECOND,
|
||||
lookup: 0.5 * durations.SECOND,
|
||||
|
|
|
@ -19,6 +19,7 @@ import * as durations from '../util/durations';
|
|||
import { sleep } from '../util/sleep';
|
||||
import { drop } from '../util/drop';
|
||||
import { createProxyAgent } from '../util/createProxyAgent';
|
||||
import type { ProxyAgent } from '../util/createProxyAgent';
|
||||
import { SocketStatus } from '../types/SocketStatus';
|
||||
import * as Errors from '../types/errors';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
@ -84,7 +85,7 @@ export class SocketManager extends EventListener {
|
|||
|
||||
private credentials?: WebAPICredentials;
|
||||
|
||||
private readonly proxyAgent?: ReturnType<typeof createProxyAgent>;
|
||||
private proxyAgent?: ProxyAgent;
|
||||
|
||||
private status = SocketStatus.CLOSED;
|
||||
|
||||
|
@ -105,10 +106,6 @@ export class SocketManager extends EventListener {
|
|||
constructor(private readonly options: SocketManagerOptions) {
|
||||
super();
|
||||
|
||||
if (options.proxyUrl) {
|
||||
this.proxyAgent = createProxyAgent(options.proxyUrl);
|
||||
}
|
||||
|
||||
this.hasStoriesDisabled = options.hasStoriesDisabled;
|
||||
}
|
||||
|
||||
|
@ -338,6 +335,11 @@ export class SocketManager extends EventListener {
|
|||
url: string;
|
||||
extraHeaders?: Record<string, string>;
|
||||
}): Promise<WebSocket> {
|
||||
// Create proxy agent lazily
|
||||
if (this.options.proxyUrl && !this.proxyAgent) {
|
||||
this.proxyAgent = await createProxyAgent(this.options.proxyUrl);
|
||||
}
|
||||
|
||||
return connectWebSocket({
|
||||
name: 'art-creator-provisioning',
|
||||
url,
|
||||
|
|
|
@ -31,6 +31,7 @@ import { toWebSafeBase64, fromWebSafeBase64 } from '../util/webSafeBase64';
|
|||
import { getBasicAuth } from '../util/getBasicAuth';
|
||||
import { createHTTPSAgent } from '../util/createHTTPSAgent';
|
||||
import { createProxyAgent } from '../util/createProxyAgent';
|
||||
import type { ProxyAgent } from '../util/createProxyAgent';
|
||||
import type { SocketStatus } from '../types/SocketStatus';
|
||||
import { VerificationTransport } from '../types/VerificationTransport';
|
||||
import { toLogFormat } from '../types/errors';
|
||||
|
@ -120,7 +121,7 @@ const GET_ATTACHMENT_CHUNK_TIMEOUT = 10 * durations.SECOND;
|
|||
type AgentCacheType = {
|
||||
[name: string]: {
|
||||
timestamp: number;
|
||||
agent: ReturnType<typeof createProxyAgent> | Agent;
|
||||
agent: ProxyAgent | Agent;
|
||||
};
|
||||
};
|
||||
const agents: AgentCacheType = {};
|
||||
|
@ -259,7 +260,7 @@ async function _promiseAjax(
|
|||
}
|
||||
agents[cacheKey] = {
|
||||
agent: proxyUrl
|
||||
? createProxyAgent(proxyUrl)
|
||||
? await createProxyAgent(proxyUrl)
|
||||
: createHTTPSAgent({
|
||||
keepAlive: !options.disableSessionResumption,
|
||||
maxCachedSessions: options.disableSessionResumption ? 0 : undefined,
|
||||
|
@ -1382,17 +1383,23 @@ export function initialize({
|
|||
log.warn(`${logId}: Done`);
|
||||
}
|
||||
|
||||
let fetchAgent: Agent;
|
||||
if (proxyUrl) {
|
||||
fetchAgent = createProxyAgent(proxyUrl);
|
||||
} else {
|
||||
fetchAgent = createHTTPSAgent({
|
||||
keepAlive: false,
|
||||
maxCachedSessions: 0,
|
||||
});
|
||||
}
|
||||
const fetchForLinkPreviews: linkPreviewFetch.FetchFn = (href, init) =>
|
||||
fetch(href, { ...init, agent: fetchAgent });
|
||||
let fetchAgent: Agent | undefined;
|
||||
const fetchForLinkPreviews: linkPreviewFetch.FetchFn = async (
|
||||
href,
|
||||
init
|
||||
) => {
|
||||
if (!fetchAgent) {
|
||||
if (proxyUrl) {
|
||||
fetchAgent = await createProxyAgent(proxyUrl);
|
||||
} else {
|
||||
fetchAgent = createHTTPSAgent({
|
||||
keepAlive: false,
|
||||
maxCachedSessions: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
return fetch(href, { ...init, agent: fetchAgent });
|
||||
};
|
||||
|
||||
// Thanks, function hoisting!
|
||||
return {
|
||||
|
|
|
@ -9,7 +9,7 @@ import { strictAssert } from '../util/assert';
|
|||
import { explodePromise } from '../util/explodePromise';
|
||||
import { getUserAgent } from '../util/getUserAgent';
|
||||
import * as durations from '../util/durations';
|
||||
import type { createProxyAgent } from '../util/createProxyAgent';
|
||||
import type { ProxyAgent } from '../util/createProxyAgent';
|
||||
import { createHTTPSAgent } from '../util/createHTTPSAgent';
|
||||
import * as log from '../logging/log';
|
||||
import * as Timers from '../Timers';
|
||||
|
@ -28,7 +28,7 @@ export type ConnectOptionsType<Resource extends IResource> = Readonly<{
|
|||
url: string;
|
||||
certificateAuthority?: string;
|
||||
version: string;
|
||||
proxyAgent?: ReturnType<typeof createProxyAgent>;
|
||||
proxyAgent?: ProxyAgent;
|
||||
timeout?: number;
|
||||
extraHeaders?: Record<string, string>;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { LoggerType } from '../../types/Logging';
|
|||
import { isOlderThan } from '../../util/timestamp';
|
||||
import { HOUR } from '../../util/durations';
|
||||
import { createProxyAgent } from '../../util/createProxyAgent';
|
||||
import type { ProxyAgent } from '../../util/createProxyAgent';
|
||||
|
||||
// It is 24 hours, but we don't want latency between server and client to be
|
||||
// count.
|
||||
|
@ -30,15 +31,11 @@ export abstract class CDSBase<
|
|||
Options extends CDSBaseOptionsType = CDSBaseOptionsType
|
||||
> {
|
||||
protected readonly logger: LoggerType;
|
||||
protected readonly proxyAgent?: ReturnType<typeof createProxyAgent>;
|
||||
protected proxyAgent?: ProxyAgent;
|
||||
protected cachedAuth?: CachedAuthType;
|
||||
|
||||
constructor(protected readonly options: Options) {
|
||||
this.logger = options.logger;
|
||||
|
||||
if (options.proxyUrl) {
|
||||
this.proxyAgent = createProxyAgent(options.proxyUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract request(
|
||||
|
@ -46,6 +43,11 @@ export abstract class CDSBase<
|
|||
): Promise<CDSResponseType>;
|
||||
|
||||
protected async getAuth(): Promise<CDSAuthType> {
|
||||
// Lazily create proxy agent
|
||||
if (!this.proxyAgent && this.options.proxyUrl) {
|
||||
this.proxyAgent = await createProxyAgent(this.options.proxyUrl);
|
||||
}
|
||||
|
||||
if (this.cachedAuth) {
|
||||
if (isOlderThan(this.cachedAuth.timestamp, CACHED_AUTH_TTL)) {
|
||||
this.cachedAuth = undefined;
|
||||
|
|
|
@ -602,7 +602,7 @@ export abstract class Updater {
|
|||
|
||||
this.logger.info(`downloadUpdate: Downloading signature ${signatureUrl}`);
|
||||
const signature = Buffer.from(
|
||||
await got(signatureUrl, getGotOptions()).text(),
|
||||
await got(signatureUrl, await getGotOptions()).text(),
|
||||
'hex'
|
||||
);
|
||||
|
||||
|
@ -614,7 +614,10 @@ export abstract class Updater {
|
|||
this.logger.info(
|
||||
`downloadUpdate: Downloading blockmap ${blockMapUrl}`
|
||||
);
|
||||
const blockMap = await got(blockMapUrl, getGotOptions()).buffer();
|
||||
const blockMap = await got(
|
||||
blockMapUrl,
|
||||
await getGotOptions()
|
||||
).buffer();
|
||||
await writeFile(tempBlockMapPath, blockMap);
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
|
@ -751,7 +754,7 @@ export abstract class Updater {
|
|||
targetUpdatePath: string,
|
||||
updateOnProgress = false
|
||||
): Promise<void> {
|
||||
const downloadStream = got.stream(updateFileUrl, getGotOptions());
|
||||
const downloadStream = got.stream(updateFileUrl, await getGotOptions());
|
||||
const writeStream = createWriteStream(targetUpdatePath);
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
|
@ -930,7 +933,7 @@ export function parseYaml(yaml: string): JSONUpdateSchema {
|
|||
|
||||
async function getUpdateYaml(): Promise<string> {
|
||||
const targetUrl = getUpdateCheckUrl();
|
||||
const body = await got(targetUrl, getGotOptions()).text();
|
||||
const body = await got(targetUrl, await getGotOptions()).text();
|
||||
|
||||
if (!body) {
|
||||
throw new Error('Got unexpected response back from update check');
|
||||
|
|
|
@ -15,6 +15,7 @@ import { strictAssert } from '../util/assert';
|
|||
import { wrapEventEmitterOnce } from '../util/wrapEventEmitterOnce';
|
||||
import type { LoggerType } from '../types/Logging';
|
||||
import { getGotOptions } from './got';
|
||||
import type { GotOptions } from './got';
|
||||
import { checkIntegrity } from './util';
|
||||
|
||||
const gunzip = promisify(nativeGunzip);
|
||||
|
@ -74,7 +75,7 @@ export type DownloadOptionsType = Readonly<{
|
|||
logger?: LoggerType;
|
||||
|
||||
// Testing
|
||||
gotOptions?: ReturnType<typeof getGotOptions>;
|
||||
gotOptions?: GotOptions;
|
||||
}>;
|
||||
|
||||
export type DownloadRangesOptionsType = Readonly<{
|
||||
|
@ -86,7 +87,7 @@ export type DownloadRangesOptionsType = Readonly<{
|
|||
chunkStatusCallback: (chunkSize: number) => void;
|
||||
|
||||
// Testing
|
||||
gotOptions?: ReturnType<typeof getGotOptions>;
|
||||
gotOptions?: GotOptions;
|
||||
}>;
|
||||
|
||||
export function getBlockMapFileName(fileName: string): string {
|
||||
|
@ -212,7 +213,7 @@ export async function prepareDownload({
|
|||
|
||||
const newBlockMapData = await got(
|
||||
getBlockMapFileName(newUrl),
|
||||
getGotOptions()
|
||||
await getGotOptions()
|
||||
).buffer();
|
||||
|
||||
const newBlockMap = await parseBlockMap(newBlockMapData);
|
||||
|
@ -343,7 +344,7 @@ export async function downloadRanges(
|
|||
logger,
|
||||
abortSignal,
|
||||
chunkStatusCallback,
|
||||
gotOptions = getGotOptions(),
|
||||
gotOptions = await getGotOptions(),
|
||||
} = options;
|
||||
|
||||
logger?.info('updater/downloadRanges: downloading ranges', ranges.length);
|
||||
|
|
|
@ -24,13 +24,15 @@ export function getCertificateAuthority(): string {
|
|||
return config.get('certificateAuthority');
|
||||
}
|
||||
|
||||
export function getGotOptions(): GotOptions {
|
||||
export type { GotOptions };
|
||||
|
||||
export async function getGotOptions(): Promise<GotOptions> {
|
||||
const certificateAuthority = getCertificateAuthority();
|
||||
const proxyUrl = getProxyUrl();
|
||||
const agent = proxyUrl
|
||||
? {
|
||||
http: createProxyAgent(proxyUrl),
|
||||
https: createProxyAgent(proxyUrl),
|
||||
http: await createProxyAgent(proxyUrl),
|
||||
https: await createProxyAgent(proxyUrl),
|
||||
}
|
||||
: {
|
||||
http: new HTTPAgent(),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ProxyAgent } from 'proxy-agent';
|
||||
import net from 'net';
|
||||
import type { ProxyAgent } from 'proxy-agent';
|
||||
import { URL } from 'url';
|
||||
import type { LookupOptions, LookupAddress } from 'dns';
|
||||
import { lookup } from 'dns/promises';
|
||||
|
@ -25,7 +25,9 @@ const SOCKS_PROTOCOLS = new Set([
|
|||
'socks5h:',
|
||||
]);
|
||||
|
||||
export function createProxyAgent(proxyUrl: string): ProxyAgent {
|
||||
export type { ProxyAgent };
|
||||
|
||||
export async function createProxyAgent(proxyUrl: string): Promise<ProxyAgent> {
|
||||
const { port: portStr, hostname: proxyHost, protocol } = new URL(proxyUrl);
|
||||
let defaultPort: number | undefined;
|
||||
if (protocol === 'http:') {
|
||||
|
@ -96,6 +98,8 @@ export function createProxyAgent(proxyUrl: string): ProxyAgent {
|
|||
}
|
||||
}
|
||||
|
||||
const { ProxyAgent } = await import('proxy-agent');
|
||||
|
||||
return new ProxyAgent({
|
||||
lookup:
|
||||
port !== undefined
|
||||
|
|
Loading…
Reference in a new issue