|
1 | 1 | 'use strict' |
2 | 2 |
|
3 | 3 | const From = require('fastify-reply-from') |
| 4 | +const WebSocketPlugin = require('fastify-websocket') |
| 5 | +const WebSocket = require('ws') |
| 6 | +const { pipeline } = require('stream') |
| 7 | +const nonWsMethods = ['DELETE', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS'] |
4 | 8 |
|
5 | 9 | module.exports = async function (fastify, opts) { |
6 | 10 | if (!opts.upstream) { |
@@ -42,12 +46,59 @@ module.exports = async function (fastify, opts) { |
42 | 46 | done(null, req) |
43 | 47 | } |
44 | 48 |
|
45 | | - fastify.all('/', { preHandler, config: opts.config || {} }, reply) |
46 | | - fastify.all('/*', { preHandler, config: opts.config || {} }, reply) |
| 49 | + if (opts.websocket) { |
| 50 | + fastify.register(WebSocketPlugin, opts.websocket) |
| 51 | + } |
| 52 | + |
| 53 | + fastify.get('/', { |
| 54 | + preHandler, |
| 55 | + config: opts.config || {}, |
| 56 | + handler, |
| 57 | + wsHandler |
| 58 | + }) |
| 59 | + fastify.get('/*', { |
| 60 | + preHandler, |
| 61 | + config: opts.config || {}, |
| 62 | + handler, |
| 63 | + wsHandler |
| 64 | + }) |
| 65 | + |
| 66 | + fastify.route({ |
| 67 | + url: '/', |
| 68 | + method: nonWsMethods, |
| 69 | + preHandler, |
| 70 | + config: opts.config || {}, |
| 71 | + handler |
| 72 | + }) |
| 73 | + fastify.route({ |
| 74 | + url: '/*', |
| 75 | + method: nonWsMethods, |
| 76 | + preHandler, |
| 77 | + config: opts.config || {}, |
| 78 | + handler |
| 79 | + }) |
47 | 80 |
|
48 | | - function reply (request, reply) { |
| 81 | + function handler (request, reply) { |
49 | 82 | var dest = request.req.url |
50 | 83 | dest = dest.replace(this.prefix, rewritePrefix) |
51 | 84 | reply.from(dest || '/', replyOpts) |
52 | 85 | } |
| 86 | + |
| 87 | + function wsHandler (conn, req) { |
| 88 | + // TODO support paths and querystrings |
| 89 | + // TODO support rewriteHeader |
| 90 | + // TODO support rewritePrefix |
| 91 | + const ws = new WebSocket(opts.upstream) |
| 92 | + const stream = WebSocket.createWebSocketStream(ws) |
| 93 | + |
| 94 | + // TODO fastify-websocket should create a logger for each connection |
| 95 | + fastify.log.info('starting websocket tunnel') |
| 96 | + pipeline(conn, stream, conn, function (err) { |
| 97 | + if (err) { |
| 98 | + fastify.log.info({ err }, 'websocket tunnel terminated with error') |
| 99 | + return |
| 100 | + } |
| 101 | + fastify.log.info('websocket tunnel terminated') |
| 102 | + }) |
| 103 | + } |
53 | 104 | } |
0 commit comments