| 8 | * - Applies a 3000 ms timeout when `isDev` is `true`. |
| 9 | */ |
| 10 | export function fetchResource( |
| 11 | url: string, |
| 12 | isDev: boolean, |
| 13 | errorMessage?: string |
| 14 | ): Promise<Buffer> { |
| 15 | return new Promise((resolve, reject) => { |
| 16 | const { protocol } = new URL(url) |
| 17 | const client = protocol === 'https:' ? https : http |
| 18 | const timeout = isDev ? 3000 : undefined |
| 19 | |
| 20 | const req = client.request( |
| 21 | url, |
| 22 | { |
| 23 | agent: getProxyAgent(), |
| 24 | headers: { |
| 25 | // The file format is based off of the user agent, make sure woff2 files are fetched |
| 26 | 'User-Agent': |
| 27 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ' + |
| 28 | 'AppleWebKit/537.36 (KHTML, like Gecko) ' + |
| 29 | 'Chrome/104.0.0.0 Safari/537.36', |
| 30 | }, |
| 31 | }, |
| 32 | (res) => { |
| 33 | if (res.statusCode !== 200) { |
| 34 | reject( |
| 35 | new Error( |
| 36 | errorMessage || |
| 37 | `Request failed: ${url} (status: ${res.statusCode})` |
| 38 | ) |
| 39 | ) |
| 40 | return |
| 41 | } |
| 42 | const chunks: Buffer[] = [] |
| 43 | res.on('data', (chunk) => chunks.push(Buffer.from(chunk))) |
| 44 | res.on('end', () => resolve(Buffer.concat(chunks))) |
| 45 | } |
| 46 | ) |
| 47 | |
| 48 | if (timeout) { |
| 49 | req.setTimeout(timeout, () => { |
| 50 | req.destroy(new Error(`Request timed out after ${timeout}ms`)) |
| 51 | }) |
| 52 | } |
| 53 | |
| 54 | req.on('error', (err) => reject(err)) |
| 55 | req.end() |
| 56 | }) |
| 57 | } |