diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-16 17:42:21 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-16 17:42:21 +0900 |
| commit | 23753ec75a1820b098defb70ba16d5d1ce22e03f (patch) | |
| tree | 499842deff9c8de1bc88921f753e36fab36aad37 /src/misc | |
| parent | feat(api): add users/groups/leave (diff) | |
| parent | Refactor request (#7814) (diff) | |
| download | misskey-23753ec75a1820b098defb70ba16d5d1ce22e03f.tar.gz misskey-23753ec75a1820b098defb70ba16d5d1ce22e03f.tar.bz2 misskey-23753ec75a1820b098defb70ba16d5d1ce22e03f.zip | |
Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
Diffstat (limited to 'src/misc')
| -rw-r--r-- | src/misc/download-url.ts | 21 | ||||
| -rw-r--r-- | src/misc/fetch.ts | 67 |
2 files changed, 57 insertions, 31 deletions
diff --git a/src/misc/download-url.ts b/src/misc/download-url.ts index 8a8640a8cd..c96b4fd1d6 100644 --- a/src/misc/download-url.ts +++ b/src/misc/download-url.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import * as stream from 'stream'; import * as util from 'util'; import got, * as Got from 'got'; -import { httpAgent, httpsAgent } from './fetch'; +import { httpAgent, httpsAgent, StatusError } from './fetch'; import config from '@/config/index'; import * as chalk from 'chalk'; import Logger from '@/services/logger'; @@ -37,6 +37,7 @@ export async function downloadUrl(url: string, path: string) { http: httpAgent, https: httpsAgent, }, + http2: false, // default retry: 0, }).on('response', (res: Got.Response) => { if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) { @@ -59,17 +60,17 @@ export async function downloadUrl(url: string, path: string) { logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`); req.destroy(); } - }).on('error', (e: any) => { - if (e.name === 'HTTPError') { - const statusCode = e.response?.statusCode; - const statusMessage = e.response?.statusMessage; - e.name = `StatusError`; - e.statusCode = statusCode; - e.message = `${statusCode} ${statusMessage}`; - } }); - await pipeline(req, fs.createWriteStream(path)); + try { + await pipeline(req, fs.createWriteStream(path)); + } catch (e) { + if (e instanceof Got.HTTPError) { + throw new StatusError(`${e.response.statusCode} ${e.response.statusMessage}`, e.response.statusCode, e.response.statusMessage); + } else { + throw e; + } + } logger.succ(`Download finished: ${chalk.cyan(url)}`); } 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; + } +} |