From ad83ddacaad1c17198e768418182ba3efec7dcdb Mon Sep 17 00:00:00 2001 From: 0div Date: Fri, 6 Jun 2025 18:21:43 -0700 Subject: [PATCH 1/7] add keepalive to all js-sdk requests going for rpcTransport, envdApi and openapi fetch --- packages/js-sdk/src/api/index.ts | 6 +++ packages/js-sdk/src/sandbox/index.ts | 79 ++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/packages/js-sdk/src/api/index.ts b/packages/js-sdk/src/api/index.ts index 4452bd8319..990dab5bb7 100644 --- a/packages/js-sdk/src/api/index.ts +++ b/packages/js-sdk/src/api/index.ts @@ -61,6 +61,12 @@ class ApiClient { }), ...config.headers, }, + fetch: (request: Request) => { + const newRequest = new Request(request, { + keepalive: true, + }) + return fetch(newRequest) + }, }) if (config.logger) { diff --git a/packages/js-sdk/src/sandbox/index.ts b/packages/js-sdk/src/sandbox/index.ts index 097891bba6..8f0bb9650e 100644 --- a/packages/js-sdk/src/sandbox/index.ts +++ b/packages/js-sdk/src/sandbox/index.ts @@ -59,7 +59,7 @@ export interface SandboxUrlOpts { * * @default false */ - useSignature?: true, + useSignature?: true /** * Use signature expiration for the URL. @@ -139,7 +139,9 @@ export class Sandbox extends SandboxApi { this.connectionConfig = new ConnectionConfig(opts) this.envdAccessToken = opts.envdAccessToken - this.envdApiUrl = `${this.connectionConfig.debug ? 'http' : 'https'}://${this.getHost(this.envdPort)}` + this.envdApiUrl = `${ + this.connectionConfig.debug ? 'http' : 'https' + }://${this.getHost(this.envdPort)}` const rpcTransport = createConnectTransport({ baseUrl: this.envdApiUrl, @@ -160,6 +162,7 @@ export class Sandbox extends SandboxApi { ...(options ?? {}), headers: headers, redirect: 'follow', + keepalive: true, } return fetch(url, options) @@ -171,7 +174,15 @@ export class Sandbox extends SandboxApi { apiUrl: this.envdApiUrl, logger: opts?.logger, accessToken: this.envdAccessToken, - headers: this.envdAccessToken ? { 'X-Access-Token': this.envdAccessToken } : { }, + headers: this.envdAccessToken + ? { 'X-Access-Token': this.envdAccessToken } + : {}, + fetch: (request: Request) => { + const newRequest = new Request(request, { + keepalive: true, + }) + return fetch(newRequest) + }, }, { version: opts?.envdVersion, @@ -275,9 +286,12 @@ export class Sandbox extends SandboxApi { const config = new ConnectionConfig(opts) const info = await this.getInfo(sandboxId, opts) - return new this( - { sandboxId, envdAccessToken: info.envdAccessToken, envdVersion: info.envdVersion, ...config } - ) as InstanceType + return new this({ + sandboxId, + envdAccessToken: info.envdAccessToken, + envdVersion: info.envdVersion, + ...config, + }) as InstanceType } /** @@ -393,12 +407,19 @@ export class Sandbox extends SandboxApi { uploadUrl(path?: string, opts?: SandboxUrlOpts) { opts = opts ?? {} - if (!this.envdAccessToken && (opts.useSignature || opts.useSignatureExpiration != undefined)) { - throw new Error('Signature can be used only when sandbox is spawned with secure option.') + if ( + !this.envdAccessToken && + (opts.useSignature || opts.useSignatureExpiration != undefined) + ) { + throw new Error( + 'Signature can be used only when sandbox is spawned with secure option.' + ) } if (!opts.useSignature && opts.useSignatureExpiration != undefined) { - throw new Error('Signature expiration can be used only when signature is set to true.') + throw new Error( + 'Signature expiration can be used only when signature is set to true.' + ) } const filePath = path ?? '' @@ -406,9 +427,13 @@ export class Sandbox extends SandboxApi { if (opts.useSignature) { const url = new URL(fileUrl) - const sig = getSignature( - { path: filePath, operation: 'write', user: defaultUsername, expirationInSeconds: opts.useSignatureExpiration, envdAccessToken: this.envdAccessToken} - ) + const sig = getSignature({ + path: filePath, + operation: 'write', + user: defaultUsername, + expirationInSeconds: opts.useSignatureExpiration, + envdAccessToken: this.envdAccessToken, + }) url.searchParams.set('signature', sig.signature) if (sig.expiration) { @@ -430,24 +455,36 @@ export class Sandbox extends SandboxApi { * * @returns URL for downloading file. */ - downloadUrl(path: string, opts?: SandboxUrlOpts) { //path: string, useSignature?: boolean, signatureExpirationInSeconds?: number) { + downloadUrl(path: string, opts?: SandboxUrlOpts) { + //path: string, useSignature?: boolean, signatureExpirationInSeconds?: number) { opts = opts ?? {} - if (!this.envdAccessToken && (opts.useSignature || opts.useSignatureExpiration != undefined)) { - throw new Error('Signature can be used only when sandbox is spawned with secure option.') + if ( + !this.envdAccessToken && + (opts.useSignature || opts.useSignatureExpiration != undefined) + ) { + throw new Error( + 'Signature can be used only when sandbox is spawned with secure option.' + ) } if (!opts.useSignature && opts.useSignatureExpiration != undefined) { - throw new Error('Signature expiration can be used only when signature is set to true.') + throw new Error( + 'Signature expiration can be used only when signature is set to true.' + ) } const fileUrl = this.fileUrl(path, defaultUsername) if (opts.useSignature) { const url = new URL(fileUrl) - const sig = getSignature( - { path, operation: 'read', user: defaultUsername, expirationInSeconds: opts.useSignatureExpiration, envdAccessToken: this.envdAccessToken} - ) + const sig = getSignature({ + path, + operation: 'read', + user: defaultUsername, + expirationInSeconds: opts.useSignatureExpiration, + envdAccessToken: this.envdAccessToken, + }) url.searchParams.set('signature', sig.signature) if (sig.expiration) { @@ -460,7 +497,6 @@ export class Sandbox extends SandboxApi { return fileUrl } - /** * Get sandbox information like sandbox ID, template, metadata, started at/end at date. * @@ -475,8 +511,7 @@ export class Sandbox extends SandboxApi { }) } - - private fileUrl(path?: string, username?: string) { + private fileUrl(path?: string, username?: string) { const url = new URL('/files', this.envdApiUrl) url.searchParams.set('username', username ?? defaultUsername) From 7bed1af3fc8cb9ceece08e221d35c9efaa648ea4 Mon Sep 17 00:00:00 2001 From: 0div Date: Mon, 9 Jun 2025 12:01:53 -0700 Subject: [PATCH 2/7] add keepalive to all python-sdk requests coming from e2b client and e2b_connect client --- packages/python-sdk/e2b/api/client/client.py | 2 +- packages/python-sdk/e2b_connect/client.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/python-sdk/e2b/api/client/client.py b/packages/python-sdk/e2b/api/client/client.py index eeffd00c86..f7bd11fc49 100644 --- a/packages/python-sdk/e2b/api/client/client.py +++ b/packages/python-sdk/e2b/api/client/client.py @@ -232,7 +232,7 @@ def get_httpx_client(self) -> httpx.Client: self._client = httpx.Client( base_url=self._base_url, cookies=self._cookies, - headers=self._headers, + headers={**self._headers, "Connection": "keep-alive"}, timeout=self._timeout, verify=self._verify_ssl, follow_redirects=self._follow_redirects, diff --git a/packages/python-sdk/e2b_connect/client.py b/packages/python-sdk/e2b_connect/client.py index f6873acb46..f0df9c643a 100644 --- a/packages/python-sdk/e2b_connect/client.py +++ b/packages/python-sdk/e2b_connect/client.py @@ -150,7 +150,10 @@ def __init__( self._codec = JSONCodec if json else ProtobufCodec self._response_type = response_type self._compressor = compressor - self._headers = {**{"user-agent": "connect-python"}, **headers} + self._headers = { + **{"user-agent": "connect-python", "Connection": "keep-alive"}, + **headers, + } self._connection_retries = 3 def _prepare_unary_request( From 35bd1453a2a33b2f005caada62e75eb9fcea1644 Mon Sep 17 00:00:00 2001 From: 0div Date: Thu, 12 Jun 2025 16:07:10 -0700 Subject: [PATCH 3/7] add keepalive header instead of fetch param in js api client --- packages/js-sdk/src/api/index.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/js-sdk/src/api/index.ts b/packages/js-sdk/src/api/index.ts index 990dab5bb7..ae6f711b4b 100644 --- a/packages/js-sdk/src/api/index.ts +++ b/packages/js-sdk/src/api/index.ts @@ -52,21 +52,15 @@ class ApiClient { this.api = createClient({ baseUrl: config.apiUrl, - // keepalive: true, // TODO: Return keepalive headers: { ...defaultHeaders, ...(config.apiKey && { 'X-API-KEY': config.apiKey }), ...(config.accessToken && { Authorization: `Bearer ${config.accessToken}`, }), + ...{ 'Keep-Alive': true }, ...config.headers, }, - fetch: (request: Request) => { - const newRequest = new Request(request, { - keepalive: true, - }) - return fetch(newRequest) - }, }) if (config.logger) { From 13fedbe2988bde0872939be87bded15b0e4ca425 Mon Sep 17 00:00:00 2001 From: 0div Date: Wed, 9 Jul 2025 11:58:11 -0700 Subject: [PATCH 4/7] await sig now that it's async --- packages/js-sdk/src/sandbox/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-sdk/src/sandbox/index.ts b/packages/js-sdk/src/sandbox/index.ts index ccf9874fcb..f69db232e8 100644 --- a/packages/js-sdk/src/sandbox/index.ts +++ b/packages/js-sdk/src/sandbox/index.ts @@ -434,7 +434,7 @@ export class Sandbox extends SandboxApi { if (opts.useSignature) { const url = new URL(fileUrl) - const sig = getSignature({ + const sig = await getSignature({ path: filePath, operation: 'write', user: defaultUsername, From 3271c4df114af60ba1774482553c413b9c8b7761 Mon Sep 17 00:00:00 2001 From: 0div Date: Thu, 10 Jul 2025 17:30:27 -0700 Subject: [PATCH 5/7] fix keep-alive header --- packages/js-sdk/src/api/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-sdk/src/api/index.ts b/packages/js-sdk/src/api/index.ts index ae6f711b4b..abacdb99ef 100644 --- a/packages/js-sdk/src/api/index.ts +++ b/packages/js-sdk/src/api/index.ts @@ -58,7 +58,7 @@ class ApiClient { ...(config.accessToken && { Authorization: `Bearer ${config.accessToken}`, }), - ...{ 'Keep-Alive': true }, + ...{ Connection: 'keep-alive' }, ...config.headers, }, }) From 04a31ca28f489ed9bae65e612522ca1cbc8c8dfb Mon Sep 17 00:00:00 2001 From: 0div Date: Thu, 10 Jul 2025 17:45:41 -0700 Subject: [PATCH 6/7] fix keep-alive header in rpc transport --- packages/js-sdk/src/sandbox/index.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/js-sdk/src/sandbox/index.ts b/packages/js-sdk/src/sandbox/index.ts index e7c12de62a..7cd01b14c2 100644 --- a/packages/js-sdk/src/sandbox/index.ts +++ b/packages/js-sdk/src/sandbox/index.ts @@ -181,14 +181,8 @@ export class Sandbox extends SandboxApi { logger: opts?.logger, accessToken: this.envdAccessToken, headers: this.envdAccessToken - ? { 'X-Access-Token': this.envdAccessToken } - : {}, - fetch: (request: Request) => { - const newRequest = new Request(request, { - keepalive: true, - }) - return fetch(newRequest) - }, + ? { 'X-Access-Token': this.envdAccessToken, Connection: 'keep-alive' } + : { Connection: 'keep-alive' }, }, { version: opts?.envdVersion, From 38e06c3375f143132bcbe8da80476aed6db1f709 Mon Sep 17 00:00:00 2001 From: 0div Date: Thu, 10 Jul 2025 17:55:00 -0700 Subject: [PATCH 7/7] fix signature username --- packages/js-sdk/src/sandbox/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-sdk/src/sandbox/index.ts b/packages/js-sdk/src/sandbox/index.ts index 7cd01b14c2..c3ae254833 100644 --- a/packages/js-sdk/src/sandbox/index.ts +++ b/packages/js-sdk/src/sandbox/index.ts @@ -431,7 +431,7 @@ export class Sandbox extends SandboxApi { const sig = await getSignature({ path: filePath, operation: 'write', - user: defaultUsername, + user: username, expirationInSeconds: opts.useSignatureExpiration, envdAccessToken: this.envdAccessToken, })