Files
Microsoft-Rewards-Script/src/util/Axios.ts
2025-12-11 17:12:45 +01:00

90 lines
2.9 KiB
TypeScript

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import axiosRetry from 'axios-retry'
import { HttpProxyAgent } from 'http-proxy-agent'
import { HttpsProxyAgent } from 'https-proxy-agent'
import { URL } from 'url'
import type { AccountProxy } from '../interface/Account'
class AxiosClient {
private instance: AxiosInstance
private account: AccountProxy
constructor(account: AccountProxy) {
this.account = account
this.instance = axios.create({
timeout: 20000
})
if (this.account.url && this.account.proxyAxios) {
const agent = this.getAgentForProxy(this.account)
this.instance.defaults.httpAgent = agent
this.instance.defaults.httpsAgent = agent
}
axiosRetry(this.instance, {
retries: 5,
retryDelay: axiosRetry.exponentialDelay,
shouldResetTimeout: true,
retryCondition: error => {
if (axiosRetry.isNetworkError(error)) return true
if (!error.response) return true
const status = error.response.status
return status === 429 || (status >= 500 && status <= 599)
}
})
}
private getAgentForProxy(proxyConfig: AccountProxy): HttpProxyAgent<string> | HttpsProxyAgent<string> {
const { url: baseUrl, port, username, password } = proxyConfig
let urlObj: URL
try {
urlObj = new URL(baseUrl)
} catch (e) {
try {
urlObj = new URL(`http://${baseUrl}`)
} catch (error) {
throw new Error(`Invalid proxy URL format: ${baseUrl}`)
}
}
const protocol = urlObj.protocol.toLowerCase()
let proxyUrl: string
if (username && password) {
urlObj.username = encodeURIComponent(username)
urlObj.password = encodeURIComponent(password)
urlObj.port = port.toString()
proxyUrl = urlObj.toString()
} else {
proxyUrl = `${protocol}//${urlObj.hostname}:${port}`
}
switch (protocol) {
case 'http:':
return new HttpProxyAgent(proxyUrl)
case 'https:':
return new HttpsProxyAgent(proxyUrl)
default:
throw new Error(`Unsupported proxy protocol: ${protocol}. Only HTTP(S) is supported!`)
}
}
public async request(config: AxiosRequestConfig, bypassProxy = false): Promise<AxiosResponse> {
if (bypassProxy) {
const bypassInstance = axios.create()
axiosRetry(bypassInstance, {
retries: 3,
retryDelay: axiosRetry.exponentialDelay
})
return bypassInstance.request(config)
}
return this.instance.request(config)
}
}
export default AxiosClient