Spaces:
Running
Running
| import { UserAgentUtil } from './user-agent.util'; | |
| export class HeadersUtil { | |
| private static readonly ACCEPT_LANGUAGES = [ | |
| 'en-US,en;q=0.9', | |
| 'en-GB,en;q=0.9', | |
| 'en-US,en;q=0.8,es;q=0.7', | |
| 'en-GB,en;q=0.8,fr;q=0.6', | |
| 'es-ES,es;q=0.9,en;q=0.8', | |
| 'fr-FR,fr;q=0.9,en;q=0.8', | |
| 'de-DE,de;q=0.9,en;q=0.8', | |
| 'it-IT,it;q=0.9,en;q=0.8', | |
| 'pt-PT,pt;q=0.9,en;q=0.8', | |
| 'ru-RU,ru;q=0.9,en;q=0.8', | |
| 'ja-JP,ja;q=0.9,en;q=0.8', | |
| 'ko-KR,ko;q=0.9,en;q=0.8', | |
| 'zh-CN,zh;q=0.9,en;q=0.8', | |
| 'nl-NL,nl;q=0.9,en;q=0.8', | |
| 'sv-SE,sv;q=0.9,en;q=0.8', | |
| 'da-DK,da;q=0.9,en;q=0.8', | |
| 'no-NO,no;q=0.9,en;q=0.8', | |
| 'fi-FI,fi;q=0.9,en;q=0.8', | |
| 'pl-PL,pl;q=0.9,en;q=0.8', | |
| 'tr-TR,tr;q=0.9,en;q=0.8', | |
| ]; | |
| private static readonly ACCEPT_ENCODINGS = [ | |
| 'gzip, deflate, br', | |
| 'gzip, deflate', | |
| 'br, gzip, deflate', | |
| 'gzip, deflate, br, zstd', | |
| 'br', | |
| 'gzip', | |
| 'deflate', | |
| 'identity', | |
| 'gzip, deflate, sdch', | |
| 'br, gzip', | |
| 'deflate, br', | |
| 'gzip, br', | |
| ]; | |
| private static readonly ACCEPT_HEADERS = [ | |
| 'application/json, text/plain, */*', | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | |
| 'application/json, text/javascript, */*; q=0.01', | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', | |
| '*/*', | |
| 'application/json', | |
| 'text/html, */*; q=0.01', | |
| 'application/json, text/plain', | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', | |
| ]; | |
| private static readonly CONNECTION_TYPES = ['keep-alive', 'close', 'upgrade']; | |
| private static readonly CACHE_CONTROL_VALUES = [ | |
| 'no-cache', | |
| 'max-age=0', | |
| 'no-cache, no-store, must-revalidate', | |
| 'public, max-age=0', | |
| 'private, max-age=0', | |
| 'no-store', | |
| 'max-age=300', | |
| 'max-age=3600', | |
| ]; | |
| private static readonly SEC_FETCH_DEST_VALUES = [ | |
| 'empty', | |
| 'document', | |
| 'script', | |
| 'style', | |
| 'image', | |
| 'font', | |
| 'object', | |
| 'embed', | |
| 'iframe', | |
| 'worker', | |
| 'sharedworker', | |
| 'serviceworker', | |
| 'audioworklet', | |
| 'paintworklet', | |
| 'manifest', | |
| 'nested-document', | |
| 'report', | |
| 'xslt', | |
| ]; | |
| private static readonly SEC_FETCH_MODE_VALUES = [ | |
| 'cors', | |
| 'no-cors', | |
| 'same-origin', | |
| 'navigate', | |
| 'websocket', | |
| ]; | |
| private static readonly SEC_FETCH_SITE_VALUES = [ | |
| 'cross-site', | |
| 'same-origin', | |
| 'same-site', | |
| 'none', | |
| ]; | |
| static getRandomHeaders(): Record<string, string | undefined> { | |
| const headers: Record<string, string | undefined> = { | |
| Accept: this.getRandomArrayElement(this.ACCEPT_HEADERS), | |
| 'User-Agent': UserAgentUtil.getRandomUserAgent(), | |
| 'Accept-Language': this.getRandomArrayElement(this.ACCEPT_LANGUAGES), | |
| 'Accept-Encoding': this.getRandomArrayElement(this.ACCEPT_ENCODINGS), | |
| Connection: this.getRandomArrayElement(this.CONNECTION_TYPES), | |
| DNT: Math.random() > 0.5 ? '1' : '0', | |
| }; | |
| // Randomly add optional headers | |
| if (Math.random() > 0.3) { | |
| headers['Cache-Control'] = this.getRandomArrayElement( | |
| this.CACHE_CONTROL_VALUES, | |
| ); | |
| } | |
| if (Math.random() > 0.5) { | |
| headers['Pragma'] = 'no-cache'; | |
| } | |
| if (Math.random() > 0.4) { | |
| headers['Sec-Fetch-Dest'] = this.getRandomArrayElement( | |
| this.SEC_FETCH_DEST_VALUES, | |
| ); | |
| headers['Sec-Fetch-Mode'] = this.getRandomArrayElement( | |
| this.SEC_FETCH_MODE_VALUES, | |
| ); | |
| headers['Sec-Fetch-Site'] = this.getRandomArrayElement( | |
| this.SEC_FETCH_SITE_VALUES, | |
| ); | |
| } | |
| if (Math.random() > 0.7) { | |
| headers['X-Requested-With'] = 'XMLHttpRequest'; | |
| } | |
| if (Math.random() > 0.6) { | |
| headers['Upgrade-Insecure-Requests'] = '1'; | |
| } | |
| // Add some random custom headers occasionally | |
| if (Math.random() > 0.8) { | |
| const customHeaders = this.getRandomCustomHeaders(); | |
| Object.assign(headers, customHeaders); | |
| } | |
| return headers; | |
| } | |
| private static getRandomCustomHeaders(): Record<string, string> { | |
| const customHeaders: Record<string, string> = {}; | |
| const possibleHeaders = [ | |
| { 'X-Forwarded-For': this.generateRandomIP() }, | |
| { 'X-Real-IP': this.generateRandomIP() }, | |
| { 'X-Client-IP': this.generateRandomIP() }, | |
| { 'CF-Connecting-IP': this.generateRandomIP() }, | |
| { 'X-Forwarded-Proto': Math.random() > 0.5 ? 'https' : 'http' }, | |
| { 'X-Forwarded-Host': 'example.com' }, | |
| { 'X-Originating-IP': this.generateRandomIP() }, | |
| { 'X-Remote-IP': this.generateRandomIP() }, | |
| { 'X-Remote-Addr': this.generateRandomIP() }, | |
| ]; | |
| // Add 1-3 random custom headers | |
| const numHeaders = Math.floor(Math.random() * 3) + 1; | |
| for (let i = 0; i < numHeaders; i++) { | |
| const randomHeader = this.getRandomArrayElement(possibleHeaders); | |
| Object.assign(customHeaders, randomHeader); | |
| } | |
| return customHeaders; | |
| } | |
| private static generateRandomIP(): string { | |
| return `${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`; | |
| } | |
| private static getRandomArrayElement<T>(array: T[]): T { | |
| return array[Math.floor(Math.random() * array.length)]; | |
| } | |
| // Specific header sets for different scenarios | |
| static getBrowserHeaders(): Record<string, string | undefined> { | |
| return { | |
| Accept: | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', | |
| 'User-Agent': | |
| UserAgentUtil.getDesktopUserAgents()[ | |
| Math.floor( | |
| Math.random() * UserAgentUtil.getDesktopUserAgents().length, | |
| ) | |
| ], | |
| 'Accept-Language': this.getRandomArrayElement(this.ACCEPT_LANGUAGES), | |
| 'Accept-Encoding': 'gzip, deflate, br', | |
| Connection: 'keep-alive', | |
| 'Upgrade-Insecure-Requests': '1', | |
| 'Sec-Fetch-Dest': 'document', | |
| 'Sec-Fetch-Mode': 'navigate', | |
| 'Sec-Fetch-Site': 'none', | |
| 'Cache-Control': 'max-age=0', | |
| }; | |
| } | |
| static getApiHeaders(): Record<string, string | undefined> { | |
| return { | |
| Accept: 'application/json, text/plain, */*', | |
| 'User-Agent': UserAgentUtil.getRandomUserAgent(), | |
| 'Accept-Language': this.getRandomArrayElement(this.ACCEPT_LANGUAGES), | |
| 'Accept-Encoding': 'gzip, deflate, br', | |
| Connection: 'keep-alive', | |
| 'Sec-Fetch-Dest': 'empty', | |
| 'Sec-Fetch-Mode': 'cors', | |
| 'Sec-Fetch-Site': 'cross-site', | |
| 'X-Requested-With': 'XMLHttpRequest', | |
| }; | |
| } | |
| static getMobileHeaders(): Record<string, string | undefined> { | |
| return { | |
| Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | |
| 'User-Agent': | |
| UserAgentUtil.getMobileUserAgents()[ | |
| Math.floor(Math.random() * UserAgentUtil.getMobileUserAgents().length) | |
| ], | |
| 'Accept-Language': this.getRandomArrayElement(this.ACCEPT_LANGUAGES), | |
| 'Accept-Encoding': 'gzip, deflate', | |
| Connection: 'keep-alive', | |
| }; | |
| } | |
| } | |