mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add logging of errors whenever ProxyAgent is used, and a test for it.
Summary: Also: - Move ProxyAgent to from app/server/utils to app/server/lib, which is the more usual place for such classes. - Refactor a helper (delayAbort) that node was reporting a leak in. Test Plan: Added a test case, and tested manually. Reviewers: JakubSerafin Reviewed By: JakubSerafin Subscribers: JakubSerafin, paulfitz Differential Revision: https://phab.getgrist.com/D3897
This commit is contained in:
26
app/server/lib/ProxyAgent.ts
Normal file
26
app/server/lib/ProxyAgent.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import {HttpsProxyAgent} from "https-proxy-agent";
|
||||
import {HttpProxyAgent} from "http-proxy-agent";
|
||||
import log from 'app/server/lib/log';
|
||||
|
||||
export function proxyAgent(requestUrl: URL): HttpProxyAgent | HttpsProxyAgent | undefined {
|
||||
const proxy = process.env.GRIST_HTTPS_PROXY;
|
||||
if (!proxy) {
|
||||
return undefined;
|
||||
}
|
||||
const ProxyAgent = requestUrl.protocol === "https:" ? HttpsProxyAgent : HttpProxyAgent;
|
||||
const agent = new ProxyAgent(proxy);
|
||||
|
||||
// Wrap the main method of ProxyAgent into a wrapper that logs errors.
|
||||
const callback = agent.callback;
|
||||
agent.callback = async function () {
|
||||
try {
|
||||
return await callback.apply(this, arguments as any);
|
||||
} catch (e) {
|
||||
// Include info helpful for diagnosing issues (but not the potentially sensitive full requestUrl).
|
||||
log.rawWarn(`ProxyAgent error ${e}`,
|
||||
{proxy, reqProtocol: requestUrl.protocol, requestOrigin: requestUrl.origin});
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
return agent;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import * as path from 'path';
|
||||
import * as tmp from 'tmp';
|
||||
import * as fse from 'fs-extra';
|
||||
import log from 'app/server/lib/log';
|
||||
import {proxyAgent} from "app/server/utils/ProxyAgent";
|
||||
import {proxyAgent} from "app/server/lib/ProxyAgent";
|
||||
import chunk = require('lodash/chunk');
|
||||
import fromPairs = require('lodash/fromPairs');
|
||||
import zipObject = require('lodash/zipObject');
|
||||
|
||||
@@ -14,7 +14,7 @@ import {makeExceptionalDocSession} from 'app/server/lib/DocSession';
|
||||
import log from 'app/server/lib/log';
|
||||
import {matchesBaseDomain} from 'app/server/lib/requestUtils';
|
||||
import {delayAbort} from 'app/server/lib/serverUtils';
|
||||
import {proxyAgent} from 'app/server/utils/ProxyAgent';
|
||||
import {proxyAgent} from 'app/server/lib/ProxyAgent';
|
||||
import {promisifyAll} from 'bluebird';
|
||||
import * as _ from 'lodash';
|
||||
import {AbortController, AbortSignal} from 'node-abort-controller';
|
||||
|
||||
@@ -178,25 +178,21 @@ export function getSupportedEngineChoices(): EngineCode[]|undefined {
|
||||
* Returns a promise that resolves in the given number of milliseconds or rejects
|
||||
* when the given signal is raised.
|
||||
*/
|
||||
export function delayAbort(msec: number, signal?: AbortSignal): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let resolved = false;
|
||||
const timeout = setTimeout(() => {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
resolve();
|
||||
}
|
||||
}, msec);
|
||||
if (signal?.addEventListener) {
|
||||
signal.addEventListener('abort', (ev) => {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
clearTimeout(timeout);
|
||||
reject(ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
export async function delayAbort(msec: number, signal?: AbortSignal): Promise<void> {
|
||||
let cleanup: () => void = () => {};
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const timeout = setTimeout(() => resolve(), msec);
|
||||
signal?.addEventListener('abort', reject);
|
||||
cleanup = () => {
|
||||
// Be careful to clean up both the timer and the listener to avoid leaks.
|
||||
clearTimeout(timeout);
|
||||
signal?.removeEventListener('abort', reject);
|
||||
};
|
||||
});
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import {HttpsProxyAgent} from "https-proxy-agent";
|
||||
import {HttpProxyAgent} from "http-proxy-agent";
|
||||
|
||||
export function proxyAgent(requestUrl: URL): HttpProxyAgent | HttpsProxyAgent | undefined {
|
||||
const proxy = process.env.GRIST_HTTPS_PROXY;
|
||||
if (!proxy) {
|
||||
return undefined;
|
||||
}
|
||||
const ProxyAgent = requestUrl.protocol === "https:" ? HttpsProxyAgent : HttpProxyAgent;
|
||||
return new ProxyAgent(proxy);
|
||||
}
|
||||
Reference in New Issue
Block a user