Skip to content

Commit 5cf0ea1

Browse files
feat: implement HTTPS agent support in ApiClient for proxy and CA certificate handling
1 parent 7253d65 commit 5cf0ea1

File tree

1 file changed

+54
-7
lines changed

1 file changed

+54
-7
lines changed

src/lib/apiClient.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
2+
import httpsProxyAgentPkg from "https-proxy-agent";
3+
const { HttpsProxyAgent } = httpsProxyAgentPkg;
4+
import * as https from "https";
5+
import * as fs from "fs";
6+
import config from "../config.js";
27

38
type RequestOptions = {
49
url: string;
@@ -54,15 +59,52 @@ class ApiResponse<T = any> {
5459
}
5560
}
5661

62+
// Utility to create HTTPS agent if needed (proxy/CA)
63+
function getAxiosAgent(): AxiosRequestConfig["httpsAgent"] | undefined {
64+
const proxyHost = config.browserstackLocalOptions.proxyHost;
65+
const proxyPort = config.browserstackLocalOptions.proxyPort;
66+
const caCertPath = config.browserstackLocalOptions.useCaCertificate;
67+
68+
// If both proxy host and port are defined
69+
if (proxyHost && proxyPort) {
70+
const proxyUrl = `http://${proxyHost}:${proxyPort}`;
71+
if (caCertPath && fs.existsSync(caCertPath)) {
72+
// Proxy + CA cert
73+
const ca = fs.readFileSync(caCertPath);
74+
return new HttpsProxyAgent({
75+
host: proxyHost,
76+
port: Number(proxyPort),
77+
ca,
78+
rejectUnauthorized: false, // Set to true if you want strict SSL
79+
});
80+
} else {
81+
// Proxy only
82+
return new HttpsProxyAgent(proxyUrl);
83+
}
84+
} else if (caCertPath && fs.existsSync(caCertPath)) {
85+
// CA only
86+
return new https.Agent({
87+
ca: fs.readFileSync(caCertPath),
88+
rejectUnauthorized: false, // Set to true for strict SSL
89+
});
90+
}
91+
// Default agent (no proxy, no CA)
92+
return undefined;
93+
}
94+
5795
class ApiClient {
5896
private instance = axios.create();
5997

98+
private get axiosAgent() {
99+
return getAxiosAgent();
100+
}
101+
60102
private async requestWrapper<T>(
61-
fn: () => Promise<AxiosResponse<T>>,
103+
fn: (agent: AxiosRequestConfig["httpsAgent"]) => Promise<AxiosResponse<T>>,
62104
raise_error: boolean = true,
63105
): Promise<ApiResponse<T>> {
64106
try {
65-
const res = await fn();
107+
const res = await fn(this.axiosAgent);
66108
return new ApiResponse<T>(res);
67109
} catch (error: any) {
68110
if (error.response && !raise_error) {
@@ -79,7 +121,8 @@ class ApiClient {
79121
raise_error = true,
80122
}: RequestOptions): Promise<ApiResponse<T>> {
81123
return this.requestWrapper<T>(
82-
() => this.instance.get<T>(url, { headers, params }),
124+
(agent) =>
125+
this.instance.get<T>(url, { headers, params, httpsAgent: agent }),
83126
raise_error,
84127
);
85128
}
@@ -91,7 +134,8 @@ class ApiClient {
91134
raise_error = true,
92135
}: RequestOptions): Promise<ApiResponse<T>> {
93136
return this.requestWrapper<T>(
94-
() => this.instance.post<T>(url, body, { headers }),
137+
(agent) =>
138+
this.instance.post<T>(url, body, { headers, httpsAgent: agent }),
95139
raise_error,
96140
);
97141
}
@@ -103,7 +147,8 @@ class ApiClient {
103147
raise_error = true,
104148
}: RequestOptions): Promise<ApiResponse<T>> {
105149
return this.requestWrapper<T>(
106-
() => this.instance.put<T>(url, body, { headers }),
150+
(agent) =>
151+
this.instance.put<T>(url, body, { headers, httpsAgent: agent }),
107152
raise_error,
108153
);
109154
}
@@ -115,7 +160,8 @@ class ApiClient {
115160
raise_error = true,
116161
}: RequestOptions): Promise<ApiResponse<T>> {
117162
return this.requestWrapper<T>(
118-
() => this.instance.patch<T>(url, body, { headers }),
163+
(agent) =>
164+
this.instance.patch<T>(url, body, { headers, httpsAgent: agent }),
119165
raise_error,
120166
);
121167
}
@@ -127,7 +173,8 @@ class ApiClient {
127173
raise_error = true,
128174
}: RequestOptions): Promise<ApiResponse<T>> {
129175
return this.requestWrapper<T>(
130-
() => this.instance.delete<T>(url, { headers, params }),
176+
(agent) =>
177+
this.instance.delete<T>(url, { headers, params, httpsAgent: agent }),
131178
raise_error,
132179
);
133180
}

0 commit comments

Comments
 (0)