UNPKG

@remotion/renderer

Version:

Render Remotion videos using Node.js or Bun

98 lines (97 loc) 3.41 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readFile = void 0; const https_1 = __importDefault(require("https")); const node_http_1 = __importDefault(require("node:http")); const redirect_status_codes_1 = require("../redirect-status-codes"); const truthy_1 = require("../truthy"); const getClient = (url) => { if (url.startsWith('https://')) { return https_1.default.get; } if (url.startsWith('http://')) { return node_http_1.default.get; } throw new Error(`Can only download URLs starting with http:// or https://, got "${url}"`); }; const readFileWithoutRedirect = (url) => { return new Promise((resolve, reject) => { const client = getClient(url); const req = client(url, // Bun 1.1.16 does not support the `headers` option typeof Bun === 'undefined' ? { headers: { 'user-agent': 'Mozilla/5.0 (@remotion/renderer - https://remotion.dev)', }, } : {}, (res) => { resolve({ request: req, response: res }); }); req.on('error', (err) => { req.destroy(); return reject(err); }); }); }; const readFile = async (url, redirectsSoFar = 0) => { if (redirectsSoFar > 10) { throw new Error(`Too many redirects while downloading ${url}`); } const { request, response } = await readFileWithoutRedirect(url); if (redirect_status_codes_1.redirectStatusCodes.includes(response.statusCode)) { if (!response.headers.location) { throw new Error(`Received a status code ${response.statusCode} but no "Location" header while calling ${response.headers.location}`); } const { origin } = new URL(url); const redirectUrl = new URL(response.headers.location, origin).toString(); request.destroy(); response.destroy(); return (0, exports.readFile)(redirectUrl, redirectsSoFar + 1); } if (response.statusCode >= 400) { const body = await tryToObtainBody(response); request.destroy(); response.destroy(); throw new Error([ `Received a status code of ${response.statusCode} while downloading file ${url}.`, body ? `The response body was:` : null, body ? `---` : null, body ? body : null, body ? `---` : null, ] .filter(truthy_1.truthy) .join('\n')); } return { request, response }; }; exports.readFile = readFile; const tryToObtainBody = async (file) => { const success = new Promise((resolve) => { let data = ''; file.on('data', (chunk) => { data += chunk; }); file.on('end', () => { resolve(data); }); // OK even when getting an error, this is just a best effort file.on('error', () => resolve(data)); }); let timeout = null; const body = await Promise.race([ success, new Promise((resolve) => { timeout = setTimeout(() => { resolve(null); }, 5000); }), ]); if (timeout) { clearTimeout(timeout); } return body; };