"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchCurl = void 0; const node_stream_1 = require("node:stream"); const AbortError_js_1 = require("./AbortError.js"); const Response_js_1 = require("./Response.js"); const utils_js_1 = require("./utils.js"); function fetchCurl(fetchRequest) { const { Curl, CurlCode, CurlFeature, CurlPause, CurlProgressFunc } = globalThis['libcurl']; const curlHandle = new Curl(); curlHandle.enable(CurlFeature.NoDataParsing); curlHandle.setOpt('URL', fetchRequest.url); curlHandle.setOpt('SSL_VERIFYPEER', false); curlHandle.enable(CurlFeature.StreamResponse); curlHandle.setStreamProgressCallback(function () { return fetchRequest['_signal']?.aborted ? process.env.DEBUG ? CurlProgressFunc.Continue : 1 : 0; }); if (fetchRequest['bodyType'] === 'String') { curlHandle.setOpt('POSTFIELDS', fetchRequest['bodyInit']); } else { const nodeReadable = (fetchRequest.body != null ? (0, utils_js_1.isNodeReadable)(fetchRequest.body) ? fetchRequest.body : node_stream_1.Readable.from(fetchRequest.body) : null); if (nodeReadable) { curlHandle.setOpt('UPLOAD', true); curlHandle.setUploadStream(nodeReadable); } } if (process.env.DEBUG) { curlHandle.setOpt('VERBOSE', true); } curlHandle.setOpt('TRANSFER_ENCODING', false); curlHandle.setOpt('HTTP_TRANSFER_DECODING', true); curlHandle.setOpt('FOLLOWLOCATION', fetchRequest.redirect === 'follow'); curlHandle.setOpt('MAXREDIRS', 20); curlHandle.setOpt('ACCEPT_ENCODING', ''); curlHandle.setOpt('CUSTOMREQUEST', fetchRequest.method); const headersSerializer = fetchRequest.headersSerializer || utils_js_1.defaultHeadersSerializer; let size; const curlHeaders = headersSerializer(fetchRequest.headers, value => { size = Number(value); }); if (size != null) { curlHandle.setOpt('INFILESIZE', size); } curlHandle.setOpt('HTTPHEADER', curlHeaders); curlHandle.enable(CurlFeature.NoHeaderParsing); return new Promise(function promiseResolver(resolve, reject) { let streamResolved = false; if (fetchRequest['_signal']) { fetchRequest['_signal'].onabort = () => { if (streamResolved) { curlHandle.pause(CurlPause.Recv); } else { reject(new AbortError_js_1.PonyfillAbortError()); curlHandle.close(); } }; } curlHandle.once('end', function endListener() { curlHandle.close(); }); curlHandle.once('error', function errorListener(error) { if (error.isCurlError && error.code === CurlCode.CURLE_ABORTED_BY_CALLBACK) { // this is expected } else { // this is unexpected reject(error); } curlHandle.close(); }); curlHandle.once('stream', function streamListener(stream, status, headersBuf) { const headersFlat = headersBuf .toString('utf8') .split(/\r?\n|\r/g) .filter(headerFilter => { if (headerFilter && !headerFilter.startsWith('HTTP/')) { if (fetchRequest.redirect === 'error' && (headerFilter.includes('location') || headerFilter.includes('Location'))) { reject(new Error('redirect is not allowed')); } return true; } return false; }); const headersInit = headersFlat.map(headerFlat => headerFlat.split(/:\s(.+)/).slice(0, 2)); resolve(new Response_js_1.PonyfillResponse(stream, { status, headers: headersInit, url: fetchRequest.url, })); streamResolved = true; }); curlHandle.perform(); }); } exports.fetchCurl = fetchCurl;