@openserv-labs/sdk 2.2.2 → 2.3.0
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/dist/tunnel.d.ts +7 -1
- package/dist/tunnel.d.ts.map +1 -1
- package/dist/tunnel.js +27 -49
- package/package.json +1 -1
package/dist/tunnel.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface RequestData {
|
|
|
16
16
|
export interface ResponseData {
|
|
17
17
|
status: number;
|
|
18
18
|
headers: Record<string, string | string[] | undefined>;
|
|
19
|
-
body:
|
|
19
|
+
body: Buffer;
|
|
20
20
|
}
|
|
21
21
|
export interface OpenServTunnelOptions {
|
|
22
22
|
/**
|
|
@@ -178,6 +178,12 @@ export declare class OpenServTunnel {
|
|
|
178
178
|
private handleWsError;
|
|
179
179
|
private logTunnelError;
|
|
180
180
|
private logConnectionErrorHint;
|
|
181
|
+
/**
|
|
182
|
+
* Send a response back through the WebSocket as a binary frame.
|
|
183
|
+
* Format: [4 bytes: metadata length (uint32 BE)][JSON metadata][raw body bytes]
|
|
184
|
+
* This preserves the body transparently — gzip, images, any bytes.
|
|
185
|
+
*/
|
|
186
|
+
private sendBinaryResponse;
|
|
181
187
|
private forwardRequest;
|
|
182
188
|
/**
|
|
183
189
|
* Initiate a graceful reconnection to the proxy server.
|
package/dist/tunnel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,gBAAgB,GAChB,WAAW,GACX,wBAAwB,GACxB,iBAAiB,GACjB,UAAU,GACV,QAAQ,GACR,SAAS,CAAA;AAEb;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,cAAc,GACd,MAAM,GACN,kBAAkB,GAClB,oBAAoB,GACpB,SAAS,GACT,UAAU,GACV,UAAU,GACV,cAAc,GACd,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,aAAa,CAAA;AAwEjB,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IACtD,IAAI,EAAE,MAAM,CAAA;CACb;AASD,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5D;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAElD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"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"}
|
package/dist/tunnel.js
CHANGED
|
@@ -137,39 +137,17 @@ async function forwardToLocalAgent(localPort, requestData) {
|
|
|
137
137
|
});
|
|
138
138
|
res.on('end', () => {
|
|
139
139
|
if (!responseTooLarge) {
|
|
140
|
-
const
|
|
141
|
-
const contentType = res.headers['content-type'] || '';
|
|
142
|
-
// Check if content is text-based (can be safely converted to string)
|
|
143
|
-
const isTextContent = contentType.includes('text/') ||
|
|
144
|
-
contentType.includes('application/json') ||
|
|
145
|
-
contentType.includes('application/xml') ||
|
|
146
|
-
contentType.includes('application/javascript') ||
|
|
147
|
-
contentType.includes('+json') ||
|
|
148
|
-
contentType.includes('+xml');
|
|
149
|
-
// For text content, convert to UTF-8 string; for binary, use base64
|
|
150
|
-
const responseBody = isTextContent
|
|
151
|
-
? responseBuffer.toString('utf8')
|
|
152
|
-
: responseBuffer.toString('base64');
|
|
140
|
+
const responseBody = Buffer.concat(chunks);
|
|
153
141
|
// Build clean response headers - strip hop-by-hop headers
|
|
154
142
|
const responseHeaders = {
|
|
155
143
|
...res.headers
|
|
156
144
|
};
|
|
157
|
-
// Remove hop-by-hop headers that shouldn't be forwarded back
|
|
158
145
|
delete responseHeaders.connection;
|
|
159
146
|
delete responseHeaders['keep-alive'];
|
|
160
147
|
delete responseHeaders['transfer-encoding'];
|
|
161
148
|
delete responseHeaders.te;
|
|
162
149
|
delete responseHeaders.trailer;
|
|
163
150
|
delete responseHeaders.upgrade;
|
|
164
|
-
// Remove original content-length - will be recalculated based on actual body
|
|
165
|
-
delete responseHeaders['content-length'];
|
|
166
|
-
// Set correct content-length based on the (possibly re-encoded) body
|
|
167
|
-
const bodyBytes = Buffer.byteLength(responseBody, 'utf8');
|
|
168
|
-
responseHeaders['content-length'] = String(bodyBytes);
|
|
169
|
-
// Add encoding header for binary responses
|
|
170
|
-
if (!isTextContent) {
|
|
171
|
-
responseHeaders['x-openserv-encoding'] = 'base64';
|
|
172
|
-
}
|
|
173
151
|
resolve({
|
|
174
152
|
status: res.statusCode || 500,
|
|
175
153
|
headers: responseHeaders,
|
|
@@ -367,11 +345,15 @@ class OpenServTunnel {
|
|
|
367
345
|
* Entry action for 'authenticating' state: send auth message.
|
|
368
346
|
*/
|
|
369
347
|
doAuthenticate() {
|
|
348
|
+
const forceTunnel = process.env.FORCE_TUNNEL === 'true';
|
|
370
349
|
const authMessage = {
|
|
371
350
|
type: 'auth',
|
|
372
351
|
apiKey: this.apiKey,
|
|
373
352
|
localPort: this.localPort
|
|
374
353
|
};
|
|
354
|
+
if (forceTunnel) {
|
|
355
|
+
authMessage.forceTunnel = true;
|
|
356
|
+
}
|
|
375
357
|
this.ws?.send(JSON.stringify(authMessage));
|
|
376
358
|
logger_1.logger.info('Authenticating...');
|
|
377
359
|
}
|
|
@@ -730,38 +712,34 @@ class OpenServTunnel {
|
|
|
730
712
|
// ============================================================================
|
|
731
713
|
// Request Forwarding
|
|
732
714
|
// ============================================================================
|
|
715
|
+
/**
|
|
716
|
+
* Send a response back through the WebSocket as a binary frame.
|
|
717
|
+
* Format: [4 bytes: metadata length (uint32 BE)][JSON metadata][raw body bytes]
|
|
718
|
+
* This preserves the body transparently — gzip, images, any bytes.
|
|
719
|
+
*/
|
|
720
|
+
sendBinaryResponse(id, status, headers, body) {
|
|
721
|
+
if (this.ws?.readyState !== ws_1.default.OPEN) {
|
|
722
|
+
logger_1.logger.warn(`Cannot send response for request ${id}: WebSocket not open`);
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const metadata = Buffer.from(JSON.stringify({ type: 'response', data: { id, status, headers } }));
|
|
726
|
+
const frame = Buffer.alloc(4 + metadata.length + body.length);
|
|
727
|
+
frame.writeUInt32BE(metadata.length, 0);
|
|
728
|
+
metadata.copy(frame, 4);
|
|
729
|
+
body.copy(frame, 4 + metadata.length);
|
|
730
|
+
this.ws.send(frame);
|
|
731
|
+
}
|
|
733
732
|
async forwardRequest(requestData) {
|
|
734
|
-
const sendResponse = (responseData) => {
|
|
735
|
-
if (this.ws?.readyState === ws_1.default.OPEN) {
|
|
736
|
-
this.ws.send(JSON.stringify({
|
|
737
|
-
type: 'response',
|
|
738
|
-
data: responseData
|
|
739
|
-
}));
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
logger_1.logger.warn(`Cannot send response for request ${responseData.id}: WebSocket not open`);
|
|
743
|
-
}
|
|
744
|
-
};
|
|
745
733
|
try {
|
|
746
734
|
const response = await forwardToLocalAgent(this.localPort, requestData);
|
|
747
|
-
|
|
748
|
-
id: requestData.id,
|
|
749
|
-
status: response.status,
|
|
750
|
-
headers: response.headers,
|
|
751
|
-
body: response.body
|
|
752
|
-
});
|
|
735
|
+
this.sendBinaryResponse(requestData.id, response.status, response.headers, response.body);
|
|
753
736
|
}
|
|
754
737
|
catch (error) {
|
|
755
738
|
logger_1.logger.error(`Error forwarding request: ${error.message}`);
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
body: JSON.stringify({
|
|
761
|
-
error: 'Bad Gateway',
|
|
762
|
-
message: error.message
|
|
763
|
-
})
|
|
764
|
-
});
|
|
739
|
+
this.sendBinaryResponse(requestData.id, 502, { 'content-type': 'application/json' }, Buffer.from(JSON.stringify({
|
|
740
|
+
error: 'Bad Gateway',
|
|
741
|
+
message: error.message
|
|
742
|
+
})));
|
|
765
743
|
}
|
|
766
744
|
}
|
|
767
745
|
/**
|