( url: string )
| 192 | |
| 193 | /** Securely download a generated media URL (or inline data URI) to a buffer. */ |
| 194 | export async function downloadFalMedia( |
| 195 | url: string |
| 196 | ): Promise<{ buffer: Buffer; contentType: string }> { |
| 197 | if (url.startsWith('data:')) { |
| 198 | const match = /^data:([^;]+);base64,(.+)$/u.exec(url) |
| 199 | if (!match) throw new Error('Invalid data URI media response') |
| 200 | const buffer = Buffer.from(match[2], 'base64') |
| 201 | assertKnownSizeWithinLimit(buffer.length, MAX_MEDIA_BYTES, 'inline media response') |
| 202 | return { contentType: match[1], buffer } |
| 203 | } |
| 204 | |
| 205 | const validation = await validateUrlWithDNS(url, 'mediaUrl') |
| 206 | if (!validation.isValid || !validation.resolvedIP) { |
| 207 | throw new Error(validation.error || 'Generated media URL failed validation') |
| 208 | } |
| 209 | |
| 210 | const response = await secureFetchWithPinnedIP(url, validation.resolvedIP, { |
| 211 | method: 'GET', |
| 212 | maxResponseBytes: MAX_MEDIA_BYTES, |
| 213 | }) |
| 214 | if (!response.ok) { |
| 215 | await readResponseTextWithLimit(response, { |
| 216 | maxBytes: DEFAULT_MAX_ERROR_BODY_BYTES, |
| 217 | label: 'generated media error response', |
| 218 | }).catch(() => '') |
| 219 | throw new Error(`Failed to download generated media: ${response.status}`) |
| 220 | } |
| 221 | |
| 222 | const contentType = response.headers.get('content-type') || 'application/octet-stream' |
| 223 | const buffer = await readResponseToBufferWithLimit(response, { |
| 224 | maxBytes: MAX_MEDIA_BYTES, |
| 225 | label: 'generated media download', |
| 226 | }) |
| 227 | return { buffer, contentType } |
| 228 | } |
| 229 | |
| 230 | export { logger as falMediaLogger } |
no test coverage detected