Skip to content

Commit 3a829e1

Browse files
authored
fix: The target websocket watch the specific url instead of upstream(… (#308)
1 parent 59cb1f8 commit 3a829e1

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

index.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,12 @@ class WebSocketProxy {
133133
this.prefixList = []
134134
}
135135

136-
addUpstream (prefix, rewritePrefix, upstream, wsClientOptions) {
136+
addUpstream (prefix, rewritePrefix, upstream, wsUpstream, wsClientOptions) {
137137
this.prefixList.push({
138138
prefix: new URL(prefix, 'ws://127.0.0.1').pathname,
139139
rewritePrefix,
140140
upstream: convertUrlToWebSocket(upstream),
141+
wsUpstream: wsUpstream ? convertUrlToWebSocket(wsUpstream) : '',
141142
wsClientOptions
142143
})
143144

@@ -148,18 +149,15 @@ class WebSocketProxy {
148149
findUpstream (request) {
149150
const source = new URL(request.url, 'ws://127.0.0.1')
150151

151-
for (const { prefix, rewritePrefix, upstream, wsClientOptions } of this.prefixList) {
152-
// If the "upstream" have path then need get the Base of url, otherwise the "target" path will be broken.
153-
// Example: upstream is "ws://localhost:22/some/path" and after this code
154-
// "target = new URL(source.pathname.replace(prefix, rewritePrefix), upstream)"
155-
// The target.pathname will be "some/some/path"
156-
const upstreamUrl = new URL(upstream)
157-
const upstreamBase = upstreamUrl.pathname && upstreamUrl.pathname !== '/'
158-
? upstreamUrl.href.replace(upstreamUrl.pathname, '')
159-
: upstream
152+
for (const { prefix, rewritePrefix, upstream, wsUpstream, wsClientOptions } of this.prefixList) {
153+
if (wsUpstream) {
154+
const target = new URL(wsUpstream)
155+
target.search = source.search
156+
return { target, wsClientOptions }
157+
}
160158

161159
if (source.pathname.startsWith(prefix)) {
162-
const target = new URL(source.pathname.replace(prefix, rewritePrefix), upstreamBase)
160+
const target = new URL(source.pathname.replace(prefix, rewritePrefix), upstream)
163161
target.search = source.search
164162
return { target, wsClientOptions }
165163
}
@@ -212,7 +210,8 @@ function setupWebSocketProxy (fastify, options, rewritePrefix) {
212210
wsProxy.addUpstream(
213211
fastify.prefix,
214212
rewritePrefix,
215-
options.wsUpstream ? options.wsUpstream : options.upstream,
213+
options.upstream,
214+
options.wsUpstream,
216215
options.wsClientOptions
217216
)
218217
// The else block is validate earlier in the code

test/websocket.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,27 +421,29 @@ test('Proxy websocket with custom upstream url', async (t) => {
421421
wss.on('connection', (ws, request) => {
422422
ws.on('message', (message, binary) => {
423423
// Also need save request.url for check from what url the message is coming.
424-
serverMessages.push([message.toString(), binary, request.url])
424+
serverMessages.push([message.toString(), binary, request.headers.host.split(':')[0], request.url])
425425
ws.send(message, { binary })
426426
})
427427
})
428428

429429
await promisify(origin.listen.bind(origin))({ port: 0 })
430+
// Host for wsUpstream and for later check.
431+
const host = '127.0.0.1'
430432
// Path for wsUpstream and for later check.
431433
const path = '/some/path'
432434
const server = Fastify()
433435
server.register(proxy, {
434436
upstream: `ws://localhost:${origin.address().port}`,
435437
// Start proxy with different upstream, added path.
436-
wsUpstream: `ws://localhost:${origin.address().port}${path}`,
438+
wsUpstream: `ws://${host}:${origin.address().port}${path}`,
437439
websocket: true
438440
})
439441

440442
await server.listen({ port: 0 })
441443
t.teardown(server.close.bind(server))
442444

443445
// Start websocket with different upstream for connect, added path.
444-
const ws = new WebSocket(`ws://localhost:${server.server.address().port}${path}`)
446+
const ws = new WebSocket(`ws://${host}:${server.server.address().port}${path}`)
445447
await once(ws, 'open')
446448

447449
const data = [{ message: 'hello', binary: false }, { message: 'fastify', binary: true, isBuffer: true }]
@@ -463,8 +465,8 @@ test('Proxy websocket with custom upstream url', async (t) => {
463465
}
464466
// Also check "path", must be the same.
465467
t.strictSame(serverMessages, [
466-
['hello', false, path],
467-
['fastify', true, path]
468+
['hello', false, host, path],
469+
['fastify', true, host, path]
468470
])
469471

470472
await Promise.all([

0 commit comments

Comments
 (0)