import { URL } from 'url' ; import { Options } from 'got-cjs' ; import http2 from 'http2-wrapper' ; import { Context } from '../context' ; import { createResolveProtocol } from '../resolve-protocol' ; /**
 * Merges original generated headers and user provided overrides.
 * All header overrides will have the original header case, because of antiscraping.
 */ export function mergeHeaders ( original , overrides ) { const fixedHeaders = new Map ( ) ; for ( const entry of Object . entries ( original ) ) { fixedHeaders . set ( entry [ 0 ] . toLowerCase ( ) , entry ) ; } for ( const entry of Object . entries ( overrides ) ) { fixedHeaders . set ( entry [ 0 ] . toLowerCase ( ) , entry ) ; } return Object . fromEntries ( fixedHeaders . values ( ) ) ; } interface StoredHeaders { 1 : Record < string , string > ; 2 : Record < string , string > ; } interface HeadersData { headers ? : StoredHeaders ; } const getResolveProtocolFunction = ( options , proxyUrl , sessionData ) => { const { resolveProtocol } = options as any ; if ( resolveProtocol ) { return resolveProtocol ; } if ( proxyUrl ) { return createResolveProtocol ( proxyUrl , sessionData as any ) ; } return http2 . auto . resolveProtocol ; } ; export async function browserHeadersHook ( options ) { const { context } = options ; const { headerGeneratorOptions , useHeaderGenerator , headerGenerator , proxyUrl , } = context as Context ; const sessionData = context . sessionData as HeadersData | undefined ; if ( ! useHeaderGenerator || ! headerGenerator ) return ; const createHeadersPair = ( ) => ( { 1 : headerGenerator . getHeaders ( { httpVersion : '1' , ... headerGeneratorOptions , } ) , 2 : headerGenerator . getHeaders ( { httpVersion : '2' , ... headerGeneratorOptions , } ) , } ) ; const url = options . url as URL ; const resolveProtocol = getResolveProtocolFunction ( options , proxyUrl , sessionData ) ; let alpnProtocol ; if ( url . protocol === 'https:' ) { alpnProtocol = ( await resolveProtocol ( { host : url . hostname , port : url . port || 443 , rejectUnauthorized : false , ALPNProtocols : [ 'h2' , 'http/1.1' ] , servername : url . hostname , } ) ) . alpnProtocol ; } const httpVersion = alpnProtocol === 'h2' ? '2' : '1' ; let generatedHeaders ; if ( sessionData ) { if ( ! sessionData . headers ) { sessionData . headers = createHeadersPair ( ) ; } generatedHeaders = sessionData . headers [ httpVersion ] ; } else { generatedHeaders = headerGenerator . getHeaders ( { httpVersion , ... headerGeneratorOptions , } ) ; } if ( ! options . decompress ) { for ( const key of Object . keys ( generatedHeaders ) ) { if ( key . toLowerCase ( ) === 'accept-encoding' ) { delete generatedHeaders [ key ] ; } } } options . headers = mergeHeaders ( generatedHeaders , options . headers as Record < string , string > ) ; }