@aikidosec/broker-client 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/client.js +41 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ docker compose up -d
|
|
|
21
21
|
## Quick Start
|
|
22
22
|
|
|
23
23
|
1. **Generate CLIENT_SECRET in Aikido UI**:
|
|
24
|
-
- Navigate to: Settings → Broker Clients → Add New Client
|
|
24
|
+
- Navigate to: Settings → [Broker Clients](https://app.aikido.dev/settings/integrations/broker/clients) → Add New Client
|
|
25
25
|
- Copy the generated `CLIENT_SECRET`
|
|
26
26
|
|
|
27
27
|
2. **Configure environment** (`.env`):
|
package/app/client.js
CHANGED
|
@@ -13,7 +13,6 @@ import dns from 'native-dns';
|
|
|
13
13
|
import { ResourceManager } from './resourceManager.js';
|
|
14
14
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
15
15
|
import { getClientId, setClientIdCache, getServerUrl, getClientSecret } from './config.js';
|
|
16
|
-
import { STREAMING_THRESHOLD } from './streaming/state.js';
|
|
17
16
|
import { registerStreamingHandlers } from './streaming/handlers.js';
|
|
18
17
|
import { initStreamingResponse } from './streaming/initStreamingResponse.js';
|
|
19
18
|
import { startStaleStreamCleanup, cleanupAllStreams } from './streaming/cleanup.js';
|
|
@@ -33,7 +32,7 @@ const DNS_SERVERS = process.env.DNS_SERVERS
|
|
|
33
32
|
: null;
|
|
34
33
|
|
|
35
34
|
// Configure axios defaults
|
|
36
|
-
const MAX_RESPONSE_SIZE =
|
|
35
|
+
const MAX_RESPONSE_SIZE = 50 * 1024 * 1024; // 50 MB (falls back to streaming if exceeded)
|
|
37
36
|
const axiosConfig = {
|
|
38
37
|
timeout: 300000,
|
|
39
38
|
maxRedirects: 5,
|
|
@@ -105,28 +104,44 @@ async function resolveInternalHostname(hostname) {
|
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
/**
|
|
108
|
-
*
|
|
109
|
-
* @param {
|
|
110
|
-
* @param {
|
|
111
|
-
* @
|
|
107
|
+
* Make an internal HTTP request with automatic fallback to streaming if buffered response is too large.
|
|
108
|
+
* @param {object} options - Request options
|
|
109
|
+
* @param {string} options.method - HTTP method
|
|
110
|
+
* @param {string} options.url - Target URL
|
|
111
|
+
* @param {object} options.headers - Request headers
|
|
112
|
+
* @param {*} options.body - Request body
|
|
113
|
+
* @param {string} options.requestId - Request ID for logging
|
|
114
|
+
* @returns {Promise<{response: object, streaming: boolean}>} Response and whether streaming was used
|
|
112
115
|
*/
|
|
113
|
-
async function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
async function forwardRequestToInternalResource ({ method, url, headers, body, requestId }) {
|
|
117
|
+
const makeRequest = async (streaming) => {
|
|
118
|
+
let requestData = {
|
|
119
|
+
method,
|
|
120
|
+
url,
|
|
116
121
|
headers,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
data: body,
|
|
123
|
+
validateStatus: () => true, // Accept all status codes
|
|
124
|
+
responseType: streaming ? 'stream' : 'arraybuffer'
|
|
125
|
+
}
|
|
126
|
+
if (streaming) {
|
|
127
|
+
requestData.maxContentLength = Infinity;
|
|
128
|
+
}
|
|
129
|
+
// if streaming, this returns a stream instantly, it does not wait for the full response
|
|
130
|
+
return await internalHttpClient.request(requestData);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Try buffered request first, fallback to streaming if response too large
|
|
134
|
+
try {
|
|
135
|
+
return { response: await makeRequest(false), useStreaming: false };
|
|
136
|
+
} catch (reqError) {
|
|
137
|
+
// Fallback to streaming if buffered request exceeded maxContentLength (axios ERR_BAD_RESPONSE)
|
|
138
|
+
if (axios.isAxiosError(reqError) && // axios does not have a specific error for maxcontent length, so we have to check message (this is about the MAX_RESPONSE_SIZE we set above)
|
|
139
|
+
reqError.code === 'ERR_BAD_RESPONSE' &&
|
|
140
|
+
reqError.message?.includes('maxContentLength')) {
|
|
141
|
+
log.warn(`Buffered request exceeded maxContentLength for ${requestId}, falling back to streaming`);
|
|
142
|
+
return { response: await makeRequest(true), useStreaming: true };
|
|
143
|
+
}
|
|
144
|
+
throw reqError;
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
|
|
@@ -342,26 +357,13 @@ socket.on('forward_request', async (data, callback) => {
|
|
|
342
357
|
}
|
|
343
358
|
}
|
|
344
359
|
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
let contentLength = null;
|
|
348
|
-
|
|
349
|
-
if (method === 'GET') {
|
|
350
|
-
contentLength = await getContentLengthViaHead(resolvedUrl, headers);
|
|
351
|
-
if (contentLength !== null && contentLength > STREAMING_THRESHOLD) {
|
|
352
|
-
useStreaming = true;
|
|
353
|
-
log.info(`Large response detected (${(contentLength / (1024 * 1024)).toFixed(2)} MB) - using streaming`);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Make the request with appropriate response type
|
|
358
|
-
const response = await internalHttpClient.request({
|
|
360
|
+
// Make the request (with automatic fallback to streaming if buffered response is too large)
|
|
361
|
+
const { response, useStreaming } = await forwardRequestToInternalResource ({
|
|
359
362
|
method,
|
|
360
363
|
url: resolvedUrl,
|
|
361
364
|
headers,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
responseType: useStreaming ? 'stream' : 'arraybuffer',
|
|
365
|
+
body,
|
|
366
|
+
requestId
|
|
365
367
|
});
|
|
366
368
|
|
|
367
369
|
if (useStreaming) {
|
package/package.json
CHANGED