summaryrefslogtreecommitdiff
path: root/src/misc/fetch.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc/fetch.ts')
-rw-r--r--src/misc/fetch.ts67
1 files changed, 46 insertions, 21 deletions
diff --git a/src/misc/fetch.ts b/src/misc/fetch.ts
index 82db2f2f8c..f4f16a27e2 100644
--- a/src/misc/fetch.ts
+++ b/src/misc/fetch.ts
@@ -1,51 +1,62 @@
import * as http from 'http';
import * as https from 'https';
import CacheableLookup from 'cacheable-lookup';
-import fetch, { HeadersInit } from 'node-fetch';
+import fetch from 'node-fetch';
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
import config from '@/config/index';
import { URL } from 'url';
-export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: HeadersInit) {
- const res = await fetch(url, {
+export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: Record<string, string>) {
+ const res = await getResponse({
+ url,
+ method: 'GET',
headers: Object.assign({
'User-Agent': config.userAgent,
Accept: accept
}, headers || {}),
- timeout,
- agent: getAgentByUrl,
+ timeout
});
- if (!res.ok) {
- throw {
- name: `StatusError`,
- statusCode: res.status,
- message: `${res.status} ${res.statusText}`,
- };
- }
-
return await res.json();
}
-export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: HeadersInit) {
- const res = await fetch(url, {
+export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: Record<string, string>) {
+ const res = await getResponse({
+ url,
+ method: 'GET',
headers: Object.assign({
'User-Agent': config.userAgent,
Accept: accept
}, headers || {}),
+ timeout
+ });
+
+ return await res.text();
+}
+
+export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
+ const timeout = args?.timeout || 10 * 1000;
+
+ const controller = new AbortController();
+ setTimeout(() => {
+ controller.abort();
+ }, timeout * 6);
+
+ const res = await fetch(args.url, {
+ method: args.method,
+ headers: args.headers,
+ body: args.body,
timeout,
+ size: args?.size || 10 * 1024 * 1024,
agent: getAgentByUrl,
+ signal: controller.signal,
});
if (!res.ok) {
- throw {
- name: `StatusError`,
- statusCode: res.status,
- message: `${res.status} ${res.statusText}`,
- };
+ throw new StatusError(`${res.status} ${res.statusText}`, res.status, res.statusText);
}
- return await res.text();
+ return res;
}
const cache = new CacheableLookup({
@@ -114,3 +125,17 @@ export function getAgentByUrl(url: URL, bypassProxy = false) {
return url.protocol == 'http:' ? httpAgent : httpsAgent;
}
}
+
+export class StatusError extends Error {
+ public statusCode: number;
+ public statusMessage?: string;
+ public isClientError: boolean;
+
+ constructor(message: string, statusCode: number, statusMessage?: string) {
+ super(message);
+ this.name = 'StatusError';
+ this.statusCode = statusCode;
+ this.statusMessage = statusMessage;
+ this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
+ }
+}