well seems like no socks on bun
This commit is contained in:
parent
93578bd030
commit
6380165a94
6 changed files with 116 additions and 137 deletions
|
|
@ -6,7 +6,7 @@ import type {
|
|||
} from './types.js';
|
||||
import { HttpError } from './types.js';
|
||||
import { ProxyManager } from './proxy-manager.js';
|
||||
import got from 'got';
|
||||
import axios, { type AxiosResponse, AxiosError } from 'axios';
|
||||
import { clear } from 'node:console';
|
||||
|
||||
export class HttpClient {
|
||||
|
|
@ -51,8 +51,7 @@ export class HttpClient {
|
|||
hasProxy: !!finalConfig.proxy
|
||||
});
|
||||
|
||||
try {
|
||||
// Single decision point for proxy type - only request-level proxy
|
||||
try { // Single decision point for proxy type - only request-level proxy
|
||||
const proxy = finalConfig.proxy;
|
||||
const useBunFetch = !proxy || ProxyManager.shouldUseBunFetch(proxy);
|
||||
|
||||
|
|
@ -92,12 +91,10 @@ export class HttpClient {
|
|||
controller.abort();
|
||||
reject(new HttpError(`Request timeout after ${timeout}ms`));
|
||||
}, timeout);
|
||||
});
|
||||
|
||||
// Create request promise (don't await here!)
|
||||
}); // Create request promise (don't await here!)
|
||||
const requestPromise = useBunFetch
|
||||
? this.fetchRequest<T>(config, controller.signal)
|
||||
: this.gotRequest<T>(config, controller.signal);
|
||||
: this.axiosRequest<T>(config, controller.signal);
|
||||
|
||||
try {
|
||||
// Race the promises
|
||||
|
|
@ -125,12 +122,9 @@ export class HttpClient {
|
|||
*/
|
||||
private async fetchRequest<T>(config: RequestConfig, signal: AbortSignal): Promise<HttpResponse<T>> {
|
||||
try {
|
||||
|
||||
const options = this.buildFetchOptions(config, signal);
|
||||
// console.log('Using fetch with proxy:', config.proxy);
|
||||
// const options = config.proxy? { proxy: config.proxy.protocol + '://' + config.proxy?.host + ':' + config.proxy?.port } : {}//this.buildGotOptions(config, signal);
|
||||
const options = this.buildFetchOptions(config, signal);
|
||||
|
||||
this.logger?.debug('Making request with fetch: ', { url: config.url, options })
|
||||
this.logger?.debug('Making request with fetch: ', { url: config.url, options })
|
||||
|
||||
const response = await fetch(config.url, options);
|
||||
|
||||
|
|
@ -141,27 +135,44 @@ export class HttpClient {
|
|||
: new HttpError(`Request failed: ${(error as Error).message}`);
|
||||
}
|
||||
} /**
|
||||
* Got implementation (simplified for SOCKS proxies)
|
||||
* Axios implementation (for SOCKS proxies)
|
||||
*/
|
||||
private async gotRequest<T>(config: RequestConfig, signal: AbortSignal): Promise<HttpResponse<T>> {
|
||||
private async axiosRequest<T>(config: RequestConfig, signal: AbortSignal): Promise<HttpResponse<T>> {
|
||||
if(config.proxy) {
|
||||
try {
|
||||
const gotClient = await ProxyManager.createGotInstance(config.proxy);
|
||||
const response = await gotClient.get(config.url);
|
||||
return this.parseGotResponse<T>(response);
|
||||
const axiosProxy = await ProxyManager.createAxiosConfig(config.proxy);
|
||||
axiosProxy.url = config.url;
|
||||
axiosProxy.method = config.method || 'GET';
|
||||
// console.log(axiosProxy)
|
||||
// const axiosConfig = {
|
||||
// ...axiosProxy,
|
||||
// url: config.url,
|
||||
// method: config.method || 'GET',
|
||||
// // headers: config.headers || {},
|
||||
// // data: config.body,
|
||||
// // signal, // Axios supports AbortSignal
|
||||
// };
|
||||
|
||||
// console.log('Making request with Axios: ', axiosConfig );
|
||||
|
||||
const response: AxiosResponse<T> = await axios.request(axiosProxy);
|
||||
return this.parseAxiosResponse<T>(response);
|
||||
} catch (error) {
|
||||
console.error('Got request error:', error);
|
||||
// Handle both AbortSignal timeout and Got-specific timeout errors
|
||||
console.error('Axios request error:', error);
|
||||
|
||||
// Handle AbortSignal timeout
|
||||
if (signal.aborted) {
|
||||
throw new HttpError(`Request timeout`);
|
||||
}
|
||||
if ((error as any).name === 'TimeoutError') {
|
||||
|
||||
// Handle Axios timeout errors
|
||||
if (error instanceof AxiosError && error.code === 'ECONNABORTED') {
|
||||
throw new HttpError(`Request timeout`);
|
||||
}
|
||||
|
||||
throw new HttpError(`Request failed: ${(error as Error).message}`);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
throw new HttpError(`Request failed: No proxy configured, use fetch instead`);
|
||||
}
|
||||
}
|
||||
|
|
@ -188,46 +199,34 @@ export class HttpClient {
|
|||
|
||||
// Add proxy (HTTP/HTTPS only) - request level only
|
||||
if (config.proxy && ProxyManager.shouldUseBunFetch(config.proxy)) {
|
||||
(options as any).proxy = ProxyManager.createBunProxyUrl(config.proxy);
|
||||
(options as any).proxy = ProxyManager.createProxyUrl(config.proxy);
|
||||
}
|
||||
|
||||
return options;
|
||||
} /**
|
||||
* Build Got options (extracted for clarity)
|
||||
* Build Axios options (for reference, though we're creating instance in ProxyManager)
|
||||
*/
|
||||
private buildGotOptions(config: RequestConfig, signal: AbortSignal): any {
|
||||
private buildAxiosOptions(config: RequestConfig, signal: AbortSignal): any {
|
||||
const options: any = {
|
||||
method: config.method || 'GET',
|
||||
headers: config.headers || {},
|
||||
signal, // Use AbortSignal instead of Got's timeout
|
||||
retry: {
|
||||
limit: 3,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
|
||||
},
|
||||
throwHttpErrors: false,
|
||||
responseType: 'json'
|
||||
signal, // Axios supports AbortSignal
|
||||
timeout: config.timeout || 30000,
|
||||
maxRedirects: 5,
|
||||
validateStatus: () => true // Don't throw on HTTP errors
|
||||
};
|
||||
|
||||
// Add body
|
||||
if (config.body && config.method !== 'GET') {
|
||||
if (typeof config.body === 'object') {
|
||||
options.json = config.body;
|
||||
options.data = config.body;
|
||||
options.headers = { 'Content-Type': 'application/json', ...options.headers };
|
||||
} else {
|
||||
options.body = config.body;
|
||||
options.data = config.body;
|
||||
options.headers = { 'Content-Type': 'text/plain', ...options.headers };
|
||||
}
|
||||
}
|
||||
|
||||
// Add SOCKS proxy via agent - request level only
|
||||
if (config.proxy && !ProxyManager.shouldUseBunFetch(config.proxy)) {
|
||||
ProxyManager.validateConfig(config.proxy);
|
||||
const agent = ProxyManager.createGotAgent(config.proxy);
|
||||
options.agent = {
|
||||
http: agent,
|
||||
https: agent
|
||||
};
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
@ -248,15 +247,14 @@ export class HttpClient {
|
|||
|
||||
return { data, status: response.status, headers, ok: response.ok };
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Got response (simplified)
|
||||
* Parse Axios response
|
||||
*/
|
||||
private parseGotResponse<T>(response: any): HttpResponse<T> {
|
||||
private parseAxiosResponse<T>(response: AxiosResponse<T>): HttpResponse<T> {
|
||||
const headers = response.headers as Record<string, string>;
|
||||
const status = response.statusCode;
|
||||
const status = response.status;
|
||||
const ok = status >= 200 && status < 300;
|
||||
const data = response.body as T;
|
||||
const data = response.data;
|
||||
|
||||
if (!ok) {
|
||||
throw new HttpError(
|
||||
|
|
@ -268,7 +266,6 @@ export class HttpClient {
|
|||
|
||||
return { data, status, headers, ok };
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified body parsing (works for fetch response)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue