Skip to content

Commit 332009c

Browse files
Merge master into feature/LSP-gamma
2 parents 8084f0c + 2dd5ed7 commit 332009c

File tree

2 files changed

+95
-2
lines changed

2 files changed

+95
-2
lines changed

packages/core/src/awsService/sagemaker/uriHandlers.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,28 @@ import { deeplinkConnect } from './commands'
99
import { ExtContext } from '../../shared/extensions'
1010
import { telemetry } from '../../shared/telemetry/telemetry'
1111

12+
const amzHeaders = [
13+
'X-Amz-Security-Token',
14+
'X-Amz-Algorithm',
15+
'X-Amz-Date',
16+
'X-Amz-SignedHeaders',
17+
'X-Amz-Credential',
18+
'X-Amz-Expires',
19+
'X-Amz-Signature',
20+
] as const
21+
1222
export function register(ctx: ExtContext) {
1323
async function connectHandler(params: ReturnType<typeof parseConnectParams>) {
1424
await telemetry.sagemaker_deeplinkConnect.run(async () => {
15-
const wsUrl = `${params.ws_url}&cell-number=${params['cell-number']}`
25+
let wsUrl = `${params.ws_url}&cell-number=${encodeURIComponent(params['cell-number'])}`
26+
27+
for (const header of amzHeaders) {
28+
const value = params[header]
29+
if (value) {
30+
wsUrl += `&${header}=${encodeURIComponent(value)}`
31+
}
32+
}
33+
1634
await deeplinkConnect(
1735
ctx,
1836
params.connection_identifier,
@@ -54,6 +72,7 @@ export function parseHyperpodConnectParams(query: SearchParams) {
5472
const optionalParams = query.getFromKeys('workspaceName', 'namespace', 'eksClusterArn')
5573
return { ...requiredParams, ...optionalParams }
5674
}
75+
5776
export function parseConnectParams(query: SearchParams) {
5877
const requiredParams = query.getFromKeysOrThrow(
5978
'connection_identifier',
@@ -66,5 +85,6 @@ export function parseConnectParams(query: SearchParams) {
6685
)
6786
const optionalParams = query.getFromKeys('app_type')
6887

69-
return { ...requiredParams, ...optionalParams }
88+
const amzHeaderParams = query.getFromKeys(...amzHeaders)
89+
return { ...requiredParams, ...optionalParams, ...amzHeaderParams }
7090
}

packages/core/src/test/awsService/sagemaker/uriHandlers.test.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,77 @@ describe('SageMaker URI handler', function () {
7676
assert.ok(deeplinkConnectStub.calledOnce)
7777
assert.deepStrictEqual(deeplinkConnectStub.firstCall.args[6], undefined)
7878
})
79+
80+
it('properly encodes cell-number with spaces and special characters', async function () {
81+
const params = {
82+
connection_identifier: 'abc123',
83+
domain: 'my-domain',
84+
user_profile: 'me',
85+
session: 'sess-xyz',
86+
ws_url: 'wss://example.com',
87+
'cell-number': 'test/data with spaces',
88+
token: 'my-token',
89+
}
90+
91+
const uri = createConnectUri(params)
92+
await handler.handleUri(uri)
93+
94+
assert.ok(deeplinkConnectStub.calledOnce)
95+
// Verify cell-number is properly encoded
96+
const expectedUrl = 'wss://example.com&cell-number=test%2Fdata%20with%20spaces'
97+
assert.deepStrictEqual(deeplinkConnectStub.firstCall.args[3], expectedUrl)
98+
})
99+
100+
it('includes AMZ headers in WebSocket URL when provided', async function () {
101+
const params = {
102+
connection_identifier: 'abc123',
103+
domain: 'my-domain',
104+
user_profile: 'me',
105+
session: 'sess-xyz',
106+
ws_url: 'wss://example.com',
107+
'cell-number': 'test123',
108+
token: 'my-token',
109+
'X-Amz-Security-Token': 'fake/token+with=special',
110+
'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
111+
'X-Amz-Date': '20240101T120000Z',
112+
'X-Amz-SignedHeaders': 'host',
113+
'X-Amz-Credential': 'AKIATEST/20240101/us-west-2/ssmmessages/aws4_request',
114+
'X-Amz-Expires': '60',
115+
'X-Amz-Signature': 'fakesignature123',
116+
}
117+
118+
const uri = createConnectUri(params)
119+
await handler.handleUri(uri)
120+
121+
assert.ok(deeplinkConnectStub.calledOnce)
122+
const actualUrl = deeplinkConnectStub.firstCall.args[3]
123+
124+
// Verify all AMZ headers are included and properly encoded
125+
assert.ok(actualUrl.includes('cell-number=test123'))
126+
assert.ok(actualUrl.includes('X-Amz-Security-Token=fake%2Ftoken%2Bwith%3Dspecial'))
127+
assert.ok(actualUrl.includes('X-Amz-Algorithm=AWS4-HMAC-SHA256'))
128+
assert.ok(actualUrl.includes('X-Amz-Date=20240101T120000Z'))
129+
assert.ok(actualUrl.includes('X-Amz-SignedHeaders=host'))
130+
assert.ok(actualUrl.includes('X-Amz-Credential=AKIATEST%2F20240101%2Fus-west-2%2Fssmmessages%2Faws4_request'))
131+
assert.ok(actualUrl.includes('X-Amz-Expires=60'))
132+
assert.ok(actualUrl.includes('X-Amz-Signature=fakesignature123'))
133+
})
134+
135+
it('works without AMZ headers', async function () {
136+
const params = {
137+
connection_identifier: 'abc123',
138+
domain: 'my-domain',
139+
user_profile: 'me',
140+
session: 'sess-xyz',
141+
ws_url: 'wss://example.com',
142+
'cell-number': 'simple',
143+
token: 'my-token',
144+
}
145+
146+
const uri = createConnectUri(params)
147+
await handler.handleUri(uri)
148+
149+
assert.ok(deeplinkConnectStub.calledOnce)
150+
assert.deepStrictEqual(deeplinkConnectStub.firstCall.args[3], 'wss://example.com&cell-number=simple')
151+
})
79152
})

0 commit comments

Comments
 (0)