UNPKG

jsforce

Version:

Salesforce API Library for JavaScript

114 lines (106 loc) 2.59 kB
import { PassThrough } from 'stream'; import { concatStreamsAsDuplex, readAll } from './util/stream'; import { HttpRequest, HttpRequestOptions, HttpResponse } from './types'; import FormData from 'form-data'; /** * */ export function createHttpRequestHandlerStreams( req: HttpRequest, options: HttpRequestOptions = {}, ) { const { body: reqBody } = req; const input = new PassThrough(); const output = new PassThrough(); const duplex = concatStreamsAsDuplex(input, output); if (typeof reqBody !== 'undefined') { setTimeout(() => { if (reqBody instanceof FormData) { duplex.end(reqBody.getBuffer()); } else { duplex.end(reqBody, 'utf8'); } }, 0); } duplex.on('response', async (res) => { if (duplex.listenerCount('complete') > 0) { const resBody = await readAll(duplex, options.encoding); duplex.emit('complete', { ...res, body: resBody, }); } }); return { input, output, stream: duplex }; } const redirectStatuses = new Set([301, 302, 303, 307, 308]); /** * */ export function isRedirect(status: number) { return redirectStatuses.has(status); } /** * */ const MAX_REDIRECT_COUNT = 10; /** * */ export function performRedirectRequest( req: HttpRequest, res: Omit<HttpResponse, 'body'>, followRedirect: NonNullable<HttpRequestOptions['followRedirect']>, counter: number, redirectCallback: (req: HttpRequest) => void, ) { if (counter >= MAX_REDIRECT_COUNT) { throw new Error('Reached to maximum redirect count'); } const redirectUrl = res.headers['location']; if (!redirectUrl) { throw new Error('No redirect URI found'); } const getRedirectRequest = typeof followRedirect === 'function' ? followRedirect : () => ({ method: 'GET' as const, url: redirectUrl, headers: req.headers, }); const nextReqParams = getRedirectRequest(redirectUrl); if (!nextReqParams) { throw new Error('Cannot handle redirect for ' + redirectUrl); } redirectCallback(nextReqParams); } /** * */ export async function executeWithTimeout<T>( execFn: () => Promise<T>, msec: number | undefined, cancelCallback?: () => void, ): Promise<T> { let timeout = false; const pid = msec != null ? setTimeout(() => { timeout = true; cancelCallback?.(); }, msec) : undefined; let res; try { res = await execFn(); } finally { if (pid) { clearTimeout(pid); } } if (timeout) { throw new Error('Request Timeout'); } return res; }