import http from 'http' ; import https from 'https' ; import { fetch } from 'ohmyfetch' ; import { parseURL } from 'ufo' ; import type { SourceFactory } from '../types' ; import { createError , cachedPromise } from '../utils' ; export const createHTTPSource = ( options ) => { const httpsAgent = new https . Agent ( { keepAlive : true } ) ; const httpAgent = new http . Agent ( { keepAlive : true } ) ; let domains = options . domains || [ ] ; if ( typeof domains === 'string' ) { domains = domains . split ( ',' ) . map ( s => s . trim ( ) ) ; } const hosts = domains . map ( domain => parseURL ( domain , 'https://' ) . host ) ; return async ( id , reqOptions ) => { const parsedUrl = parseURL ( id , 'https://' ) ; if ( ! parsedUrl . host ) { throw createError ( 'Hostname is missing: ' + id , 403 ) ; } if ( ! reqOptions ?. bypassDomain && ! hosts . find ( host => parsedUrl . host === host ) ) { throw createError ( 'Forbidden host: ' + parsedUrl . host , 403 ) ; } const response = await fetch ( id , { agent : id . startsWith ( 'https' ) ? httpsAgent : httpAgent } ) ; if ( ! response . ok ) { throw createError ( response . statusText || 'fetch error' , response . status || 500 ) ; } let maxAge = options . maxAge || 300 ; const _cacheControl = response . headers . get ( 'cache-control' ) ; if ( _cacheControl ) { const m = _cacheControl . match ( /max-age=(\d+)/ ) ; if ( m && m [ 1 ] ) { maxAge = parseInt ( m [ 1 ] ) ; } } let mtime ; const _lastModified = response . headers . get ( 'last-modified' ) ; if ( _lastModified ) { mtime = new Date ( _lastModified ) ; } return { mtime , maxAge , getData : cachedPromise ( ( ) => response . buffer ( ) ) } ; } ; } ;