diff --git a/src/main/ssh/ssh-relay-endpoints.test.ts b/src/main/ssh/ssh-relay-endpoints.test.ts new file mode 100644 index 00000000000..5b001497ecf --- /dev/null +++ b/src/main/ssh/ssh-relay-endpoints.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest' +import { relayEndpointForHost } from './ssh-relay-endpoints' +import { getRemoteHostPlatform } from './ssh-remote-platform' + +describe('ssh-relay-endpoints', () => { + describe('relayEndpointForHost', () => { + it('returns the full path for a posix host if length <= 107', () => { + const hostPlatform = getRemoteHostPlatform('linux-x64') + const remoteDir = '/home/user/.orca-remote/relay' + const sockName = 'relay.sock' + const result = relayEndpointForHost(hostPlatform, remoteDir, sockName) + expect(result).toBe('/home/user/.orca-remote/relay/relay.sock') + }) + + it('hashes the path and uses parent dir if length > 107 and parent dir fits', () => { + const hostPlatform = getRemoteHostPlatform('linux-x64') + // parent dir is 79 bytes. 79 + 30 (relay-v1.0.0/relay-12345.sock) = 109 > 107 + const remoteDir = + '/home/a-seventy-nine-byte-long-path-up-to-here-that-fits-nicely-X/.orca-remote/relay-v1.0.0' + const sockName = 'relay-12345.sock' + const result = relayEndpointForHost(hostPlatform, remoteDir, sockName) + expect(result).toMatch( + /^\/home\/a-seventy-nine-byte-long-path-up-to-here-that-fits-nicely-X\/\.orca-remote\/[a-f0-9]{12}\.sock$/ + ) + expect(Buffer.byteLength(result, 'utf8')).toBeLessThanOrEqual(107) + }) + + it('falls back to /tmp if even the parent dir hashed path is too long (> 107)', () => { + const hostPlatform = getRemoteHostPlatform('linux-x64') + const remoteDir = + '/home/extremely-long-user-name-that-is-so-long-it-completely-fills-the-entire-buffer-by-itself-and-leaves-no-room-for-parent-dir/.orca-remote/relay-v1.0.0' + const sockName = 'relay.sock' + const result = relayEndpointForHost(hostPlatform, remoteDir, sockName) + expect(result).toMatch(/^\/tmp\/orca-[a-f0-9]{12}\.sock$/) + expect(Buffer.byteLength(result, 'utf8')).toBeLessThanOrEqual(107) + }) + + it('returns windows named pipe format for windows host', () => { + const hostPlatform = getRemoteHostPlatform('win32-x64') + const remoteDir = 'C:/Users/user/.orca-remote/relay' + const sockName = 'relay.sock' + const result = relayEndpointForHost(hostPlatform, remoteDir, sockName) + expect(result.startsWith('\\\\.\\pipe\\orca-relay-')).toBe(true) + }) + }) +}) diff --git a/src/main/ssh/ssh-relay-endpoints.ts b/src/main/ssh/ssh-relay-endpoints.ts index bcf1f86aae9..5fb0c32ce4f 100644 --- a/src/main/ssh/ssh-relay-endpoints.ts +++ b/src/main/ssh/ssh-relay-endpoints.ts @@ -14,7 +14,19 @@ export function relayEndpointForHost( sockName: string ): string { if (!isWindowsRemoteHost(hostPlatform)) { - return joinRemotePath(hostPlatform, remoteDir, sockName) + const fullPath = joinRemotePath(hostPlatform, remoteDir, sockName) + if (Buffer.byteLength(fullPath, 'utf8') > 107) { + const parentDir = remoteDir.includes('/relay-') + ? remoteDir.substring(0, remoteDir.lastIndexOf('/')) + : remoteDir + const hash = createHash('sha256').update(fullPath).digest('hex').slice(0, 12) + const shortened = joinRemotePath(hostPlatform, parentDir, `${hash}.sock`) + if (Buffer.byteLength(shortened, 'utf8') <= 107) { + return shortened + } + return `/tmp/orca-${hash}.sock` + } + return fullPath } const endpointHash = createHash('sha256') .update(`${remoteDir}\0${sockName}`)