Skip to content

Commit c4b6aef

Browse files
committed
fix(devframe): advertise wss for a shared TLS server
1 parent e54fde6 commit c4b6aef

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎packages/devframe/src/adapters/__tests__/initiate.test.ts‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { DevframeNodeContext, DevframeRpcClientFunctions, DevframeRpcServerFunctions } from '../../types'
22
import { mkdtempSync, writeFileSync } from 'node:fs'
33
import { createServer } from 'node:http'
4+
import { createSecureServer } from 'node:http2'
45
import { tmpdir } from 'node:os'
56
import { join } from 'node:path'
67
import { defineDevframe } from 'devframe'
@@ -10,6 +11,7 @@ import { getPort } from 'get-port-please'
1011
import { describe, expect, it, vi } from 'vitest'
1112
import { WebSocket } from 'ws'
1213
import { getTempAuthCode } from '../../node/auth/state'
14+
import { getInternalContext } from '../../node/hub-internals/context'
1315
import { initDevframe } from '../initiate'
1416

1517
const HANDSHAKE = { authToken: '', ua: 'test', origin: 'http://localhost' }
@@ -206,6 +208,30 @@ describe('adapters/handler', () => {
206208
}
207209
})
208210

211+
it('shared-server tier: a TLS host server advertises wss://', async () => {
212+
const host = '127.0.0.1'
213+
const server = createSecureServer({ allowHTTP1: true })
214+
await new Promise<void>(resolve => server.listen(0, host, resolve))
215+
const { port } = server.address() as { port: number }
216+
const devtools = initDevframe(defineTestDef('handler-tls'), {
217+
base: '/__handler-tls/',
218+
auth: false,
219+
host,
220+
server: server as any,
221+
})
222+
223+
try {
224+
await devtools.ready
225+
expect(getInternalContext(await devtools.context).wsEndpoint).toEqual({
226+
url: `wss://localhost:${port}/__handler-tls/__ws`,
227+
})
228+
}
229+
finally {
230+
await devtools.close()
231+
await new Promise<void>(resolve => server.close(() => resolve()))
232+
}
233+
})
234+
209235
it('ws.url tier: advertises the external endpoint verbatim, owns no transport', async () => {
210236
const devtools = initDevframe(defineTestDef('handler-remote'), { base: '/__handler-remote/', ws: { url: 'wss://devtools.example.com/relay/__ws' } })
211237

‎packages/devframe/src/node/instance-shell.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { DevframeInstanceRecord, DevframeInstanceRegistration } from './ins
1414
import type { ContextRpcServer } from './rpc-core'
1515
import { createServer } from 'node:http'
1616
import process from 'node:process'
17+
import { Server as TlsServer } from 'node:tls'
1718
import { validateOriginCandidate } from 'devframe/utils/origin'
1819
import { joinURL, withLeadingSlash, withoutLeadingSlash, withoutTrailingSlash } from 'devframe/utils/url'
1920
import { defineHandler, H3 as H3App, toNodeHandler } from 'h3'
@@ -143,9 +144,12 @@ async function bindHttpAndWs(options: BindHttpAndWsOptions): Promise<StartedServ
143144

144145
const address = httpServer.address()
145146
const resolvedPort = typeof address === 'object' && address ? address.port : port
146-
const origin = normalizeHttpServerUrl(bindHost, resolvedPort)
147+
const secure = httpServer instanceof TlsServer
148+
const origin = secure
149+
? `https://${formatHostForUrl(bindHost)}:${resolvedPort}`
150+
: normalizeHttpServerUrl(bindHost, resolvedPort)
147151
const internal = getInternalContext(context)
148-
const wsUrl = `ws://${formatHostForUrl(bindHost)}:${resolvedPort}${options.path ?? ''}`
152+
const wsUrl = `${secure ? 'wss' : 'ws'}://${formatHostForUrl(bindHost)}:${resolvedPort}${options.path ?? ''}`
149153
if (websocket)
150154
internal.setWsEndpoint({ url: wsUrl })
151155

0 commit comments

Comments
 (0)