well seems like no socks on bun

This commit is contained in:
Bojan Kucera 2025-06-08 00:01:27 -04:00
parent 93578bd030
commit 6380165a94
6 changed files with 116 additions and 137 deletions

View file

@ -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)
*/