diff options
Diffstat (limited to 'src/misc/fetch.ts')
| -rw-r--r-- | src/misc/fetch.ts | 67 |
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; + } +} |