@fastify/websocket
Advanced tools
Comparing version 5.0.0 to 6.0.0
/// <reference types="node" /> | ||
import { IncomingMessage, ServerResponse, Server } from 'http'; | ||
import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance } from 'fastify'; | ||
import { FastifyRequest, FastifyPluginCallback, RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestGenericInterface, ContextConfigDefault, FastifyInstance} from 'fastify'; | ||
import * as fastify from 'fastify'; | ||
@@ -21,4 +21,4 @@ import * as WebSocket from 'ws'; | ||
interface FastifyInstance<RawServer, RawRequest, RawReply> { | ||
get: RouteShorthandMethod<RawServer, RawRequest, RawReply> | ||
interface FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider> { | ||
get: RouteShorthandMethod<RawServer, RawRequest, RawReply, TypeProvider>, | ||
websocketServer: WebSocket.Server, | ||
@@ -25,0 +25,0 @@ } |
16
index.js
@@ -84,2 +84,3 @@ 'use strict' | ||
fastify.addHook('onError', (request, reply, error, done) => { | ||
/* istanbul ignore next */ | ||
if (request.raw[kWs]) { | ||
@@ -96,2 +97,9 @@ // Hijack reply to prevent fastify from sending the error after onError hooks are done running | ||
fastify.addHook('onResponse', (request, reply, error, done) => { | ||
if (request.ws) { | ||
request.raw[kWs].destroy() | ||
} | ||
done() | ||
}) | ||
fastify.addHook('onRoute', routeOptions => { | ||
@@ -103,3 +111,5 @@ let isWebsocketRoute = false | ||
if (routeOptions.websocket || routeOptions.wsHandler) { | ||
if (routeOptions.method !== 'GET') { | ||
if (routeOptions.method === 'HEAD') { | ||
return | ||
} else if (routeOptions.method !== 'GET') { | ||
throw new Error('websocket handler can only be declared in GET method') | ||
@@ -112,3 +122,3 @@ } | ||
wsHandler = routeOptions.handler | ||
handler = function (request, reply) { | ||
handler = function (_, reply) { | ||
reply.code(404).send() | ||
@@ -178,3 +188,3 @@ } | ||
function defaultErrorHandler (error, conn, request, reply) { | ||
function defaultErrorHandler (error, conn, request) { | ||
// Before destroying the connection, we attach an error listener. | ||
@@ -181,0 +191,0 @@ // Since we already handled the error, adding this listener prevents the ws |
{ | ||
"name": "@fastify/websocket", | ||
"version": "5.0.0", | ||
"version": "6.0.0", | ||
"description": "basic websocket support for fastify", | ||
@@ -33,3 +33,3 @@ "main": "index.js", | ||
"@types/ws": "^8.2.2", | ||
"fastify": "^3.25.3", | ||
"fastify": "^4.0.0-rc.2", | ||
"pre-commit": "^1.2.2", | ||
@@ -36,0 +36,0 @@ "snazzy": "^9.0.0", |
104
README.md
@@ -1,5 +0,5 @@ | ||
# fastify-websocket | ||
# @fastify/websocket | ||
![CI](https://github.com/fastify/fastify-websocket/workflows/CI/badge.svg) | ||
[![NPM version](https://img.shields.io/npm/v/fastify-websocket.svg?style=flat)](https://www.npmjs.com/package/fastify-websocket) | ||
[![NPM version](https://img.shields.io/npm/v/@fastify/websocket.svg?style=flat)](https://www.npmjs.com/package/@fastify/websocket) | ||
[![Known Vulnerabilities](https://snyk.io/test/github/fastify/fastify-websocket/badge.svg)](https://snyk.io/test/github/fastify/fastify-websocket) | ||
@@ -14,5 +14,5 @@ [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) | ||
```shell | ||
npm install fastify-websocket --save | ||
npm install @fastify/websocket --save | ||
# or | ||
yarn add fastify-websocket | ||
yarn add @fastify/websocket | ||
``` | ||
@@ -36,8 +36,9 @@ | ||
const fastify = require('fastify')() | ||
fastify.register(require('fastify-websocket')) | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
fastify.register(require('@fastify/websocket')) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
}) | ||
}) | ||
@@ -63,18 +64,19 @@ }) | ||
fastify.register(require('fastify-websocket'), { | ||
fastify.register(require('@fastify/websocket'), { | ||
options: { maxPayload: 1048576 } | ||
}) | ||
fastify.get('/*', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from wildcard route') | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from wildcard route') | ||
}) | ||
}) | ||
}) | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
fastify.get('/', { websocket: true }, (connection /* SocketStream */, req /* FastifyRequest */) => { | ||
connection.socket.on('message', message => { | ||
// message.toString() === 'hi from client' | ||
connection.socket.send('hi from server') | ||
}) | ||
}) | ||
@@ -109,3 +111,3 @@ }) | ||
Routes registered with `fastify-websocket` respect the Fastify plugin encapsulation contexts, and so will run any hooks that have been registered. This means the same route hooks you might use for authentication or error handling of plain old HTTP handlers will apply to websocket handlers as well. | ||
Routes registered with `@fastify/websocket` respect the Fastify plugin encapsulation contexts, and so will run any hooks that have been registered. This means the same route hooks you might use for authentication or error handling of plain old HTTP handlers will apply to websocket handlers as well. | ||
@@ -131,11 +133,10 @@ ```js | ||
- You can access the fastify server via `this` in your handlers | ||
- When using `fastify-websocket`, it needs to be registered before all routes in order to be able to intercept websocket connections to existing routes and close the connection on non-websocket routes. | ||
- When using `@fastify/websocket`, it needs to be registered before all routes in order to be able to intercept websocket connections to existing routes and close the connection on non-websocket routes. | ||
```js | ||
'use strict' | ||
import Fastify from 'fastify' | ||
const fastify = require('fastify')() | ||
const fastify = Fastify() | ||
await fastify.register(require('@fastify/websocket')) | ||
fastify.register(require('fastify-websocket')) | ||
fastify.get('/', { websocket: true }, function wsHandler (connection, req) { | ||
@@ -151,8 +152,3 @@ // bound to fastify server | ||
fastify.listen(3000, err => { | ||
if (err) { | ||
fastify.log.error(err) | ||
process.exit(1) | ||
} | ||
}) | ||
await fastify.listen({ port: 3000 }) | ||
``` | ||
@@ -171,3 +167,3 @@ | ||
fastify.register(require('fastify-websocket'), { | ||
fastify.register(require('@fastify/websocket'), { | ||
handle, | ||
@@ -177,18 +173,20 @@ options: { maxPayload: 1048576 } | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/hello', | ||
handler: (req, reply) => { | ||
// this will handle http requests | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: (conn, req) => { | ||
// this will handle websockets connections | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
fastify.register(async function () { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/hello', | ||
handler: (req, reply) => { | ||
// this will handle http requests | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: (conn, req) => { | ||
// this will handle websockets connections | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
conn.once('data', chunk => { | ||
conn.end() | ||
}) | ||
} | ||
conn.once('data', chunk => { | ||
conn.end() | ||
}) | ||
} | ||
}) | ||
}) | ||
@@ -213,3 +211,3 @@ | ||
fastify.register(require('fastify-websocket'), { | ||
fastify.register(require('@fastify/websocket'), { | ||
errorHandler: function (error, conn /* SocketStream */, req /* FastifyRequest */, reply /* FastifyReply */) { | ||
@@ -248,3 +246,3 @@ // Do stuff | ||
`fastify-websocket` accept these options for [`ws`](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback) : | ||
`@fastify/websocket` accept these options for [`ws`](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback) : | ||
@@ -263,7 +261,7 @@ - `host` - The hostname where to bind the server. | ||
_**NB** By default if you do not provide a `server` option `fastify-websocket` will bind your websocket server instance to the scoped `fastify` instance._ | ||
_**NB** By default if you do not provide a `server` option `@fastify/websocket` will bind your websocket server instance to the scoped `fastify` instance._ | ||
_**NB** The `path` option from `ws` should not be provided since the routing is handled by fastify itself_ | ||
_**NB** The `noServer` option from `ws` should not be provided since the point of fastify-websocket is to listen on the fastify server. If you want a custom server, you can use the `server` option, and if you want more control, you can use the `ws` library directly_ | ||
_**NB** The `noServer` option from `ws` should not be provided since the point of @fastify/websocket is to listen on the fastify server. If you want a custom server, you can use the `server` option, and if you want more control, you can use the `ws` library directly_ | ||
@@ -270,0 +268,0 @@ You can also pass the following as `connectionOptions` for [createWebSocketStream](https://github.com/websockets/ws/blob/master/doc/ws.md#createwebsocketstreamwebsocket-options). |
474
test/base.js
@@ -10,14 +10,19 @@ 'use strict' | ||
const WebSocket = require('ws') | ||
const { once, on } = require('events') | ||
let timersPromises | ||
test('Should expose a websocket', (t) => { | ||
t.plan(3) | ||
try { | ||
timersPromises = require('timers/promises') | ||
} catch {} | ||
test('Should expose a websocket', async (t) => { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
t.teardown(() => fastify.close()) | ||
fastify.register(fastifyWebsocket) | ||
await fastify.register(fastifyWebsocket) | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.setEncoding('utf8') | ||
connection.write('hello client') | ||
t.teardown(() => connection.destroy()) | ||
@@ -27,2 +32,3 @@ | ||
t.equal(chunk, 'hello server') | ||
connection.write('hello client') | ||
connection.end() | ||
@@ -32,20 +38,17 @@ }) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
client.once('data', (chunk) => { | ||
t.equal(chunk, 'hello client') | ||
client.end() | ||
}) | ||
}) | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello client') | ||
client.end() | ||
}) | ||
test('Should fail if custom errorHandler is not a function', (t) => { | ||
test('Should fail if custom errorHandler is not a function', async (t) => { | ||
t.plan(2) | ||
@@ -56,17 +59,21 @@ | ||
fastify | ||
.register(fastifyWebsocket, { errorHandler: {} }) | ||
.after(err => t.equal(err.message, 'invalid errorHandler function')) | ||
try { | ||
await fastify.register(fastifyWebsocket, { errorHandler: {} }) | ||
} catch (err) { | ||
t.equal(err.message, 'invalid errorHandler function') | ||
} | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
t.teardown(() => connection.destroy()) | ||
}) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
}) | ||
try { | ||
await fastify.listen({ port: 0 }) | ||
} catch (err) { | ||
t.equal(err.message, 'invalid errorHandler function') | ||
} | ||
}) | ||
test('Should run custom errorHandler on wildcard route handler error', (t) => { | ||
t.plan(2) | ||
test('Should run custom errorHandler on wildcard route handler error', async (t) => { | ||
t.plan(1) | ||
@@ -76,9 +83,15 @@ const fastify = Fastify() | ||
fastify.register(fastifyWebsocket, { | ||
errorHandler: function (error, connection) { | ||
let _resolve | ||
const p = new Promise((resolve) => { | ||
_resolve = resolve | ||
}) | ||
await fastify.register(fastifyWebsocket, { | ||
errorHandler: function (error) { | ||
t.equal(error.message, 'Fail') | ||
_resolve() | ||
} | ||
}) | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
fastify.get('/*', { websocket: true }, (conn) => { | ||
conn.pipe(conn) | ||
@@ -89,26 +102,29 @@ t.teardown(() => conn.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
}) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
await p | ||
}) | ||
test('Should run custom errorHandler on error inside websocket handler', (t) => { | ||
t.plan(2) | ||
test('Should run custom errorHandler on error inside websocket handler', async (t) => { | ||
const fastify = Fastify() | ||
t.teardown(() => fastify.close()) | ||
let _resolve | ||
const p = new Promise((resolve) => { | ||
_resolve = resolve | ||
}) | ||
const options = { | ||
errorHandler: function (error, connection) { | ||
errorHandler: function (error) { | ||
t.equal(error.message, 'Fail') | ||
_resolve() | ||
} | ||
} | ||
fastify.register(fastifyWebsocket, options) | ||
await fastify.register(fastifyWebsocket, options) | ||
fastify.get('/', { websocket: true }, function wsHandler (conn, request) { | ||
fastify.get('/', { websocket: true }, function wsHandler (conn) { | ||
conn.pipe(conn) | ||
@@ -119,26 +135,29 @@ t.teardown(() => conn.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
}) | ||
await p | ||
}) | ||
test('Should run custom errorHandler on error inside async websocket handler', (t) => { | ||
t.plan(2) | ||
test('Should run custom errorHandler on error inside async websocket handler', async (t) => { | ||
const fastify = Fastify() | ||
t.teardown(() => fastify.close()) | ||
let _resolve | ||
const p = new Promise((resolve) => { | ||
_resolve = resolve | ||
}) | ||
const options = { | ||
errorHandler: function (error, connection) { | ||
errorHandler: function (error) { | ||
t.equal(error.message, 'Fail') | ||
_resolve() | ||
} | ||
} | ||
fastify.register(fastifyWebsocket, options) | ||
await fastify.register(fastifyWebsocket, options) | ||
fastify.get('/', { websocket: true }, async function wsHandler (conn, request) { | ||
fastify.get('/', { websocket: true }, async function wsHandler (conn) { | ||
conn.pipe(conn) | ||
@@ -149,13 +168,11 @@ t.teardown(() => conn.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
}) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
await p | ||
}) | ||
test('Should be able to pass custom options to websocket-stream', (t) => { | ||
t.plan(3) | ||
test('Should be able to pass custom options to websocket-stream', async (t) => { | ||
t.plan(2) | ||
@@ -173,5 +190,5 @@ const fastify = Fastify() | ||
fastify.register(fastifyWebsocket, { options }) | ||
await fastify.register(fastifyWebsocket, { options }) | ||
fastify.get('/*', { websocket: true }, (connection, request) => { | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
@@ -181,34 +198,26 @@ t.teardown(() => connection.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const clientOptions = { headers: { 'x-custom-header': 'fastify is awesome !' } } | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const clientOptions = { headers: { 'x-custom-header': 'fastify is awesome !' } } | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.once('data', (chunk) => { | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
}) | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
test('Should warn if path option is provided to websocket-stream', (t) => { | ||
t.plan(4) | ||
test('Should warn if path option is provided to websocket-stream', async (t) => { | ||
t.plan(3) | ||
const logStream = split(JSON.parse) | ||
let fastify | ||
try { | ||
fastify = Fastify({ | ||
logger: { | ||
stream: logStream, | ||
level: 'warn' | ||
} | ||
}) | ||
} catch (e) { | ||
t.fail() | ||
} | ||
const fastify = Fastify({ | ||
logger: { | ||
stream: logStream, | ||
level: 'warn' | ||
} | ||
}) | ||
@@ -223,5 +232,5 @@ logStream.once('data', line => { | ||
const options = { path: '/' } | ||
fastify.register(fastifyWebsocket, { options }) | ||
await fastify.register(fastifyWebsocket, { options }) | ||
fastify.get('/*', { websocket: true }, (connection, request) => { | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
@@ -231,23 +240,18 @@ t.teardown(() => connection.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const clientOptions = { headers: { 'x-custom-header': 'fastify is awesome !' } } | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const clientOptions = { headers: { 'x-custom-header': 'fastify is awesome !' } } | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port, clientOptions) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.once('data', (chunk) => { | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
}) | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
test('Should be able to pass a custom server option to websocket-stream', (t) => { | ||
t.plan(2) | ||
test('Should be able to pass a custom server option to websocket-stream', async (t) => { | ||
// We create an external server | ||
@@ -272,5 +276,5 @@ const externalServerPort = 3000 | ||
fastify.register(fastifyWebsocket, { options }) | ||
await fastify.register(fastifyWebsocket, { options }) | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.pipe(connection) | ||
@@ -280,17 +284,14 @@ t.teardown(() => connection.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.ready() | ||
const ws = new WebSocket('ws://localhost:' + externalServerPort) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const ws = new WebSocket('ws://localhost:' + externalServerPort) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.setEncoding('utf8') | ||
client.write('hello') | ||
client.once('data', (chunk) => { | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
}) | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello') | ||
client.end() | ||
}) | ||
@@ -309,7 +310,7 @@ | ||
fastify.get('/*', { websocket: true }, (connection, request) => { | ||
fastify.get('/*', { websocket: true }, (connection) => { | ||
connection.destroy() | ||
}) | ||
fastify.listen(0, (err) => { | ||
fastify.listen({ port: 0 }, (err) => { | ||
t.error(err) | ||
@@ -323,4 +324,4 @@ | ||
test('Should be able to pass custom connectionOptions to createWebSocketStream', (t) => { | ||
t.plan(3) | ||
test('Should be able to pass custom connectionOptions to createWebSocketStream', async (t) => { | ||
t.plan(2) | ||
@@ -334,5 +335,10 @@ const fastify = Fastify() | ||
fastify.register(fastifyWebsocket, { connectionOptions }) | ||
await fastify.register(fastifyWebsocket, { connectionOptions }) | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
let _resolve | ||
const p = new Promise((resolve) => { | ||
_resolve = resolve | ||
}) | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
// readableObjectMode was added in Node v12.3.0 so for earlier versions | ||
@@ -349,2 +355,3 @@ // we check the encapsulated readable state directly | ||
t.equal(message, 'Hello') | ||
_resolve() | ||
}) | ||
@@ -354,22 +361,22 @@ t.teardown(() => connection.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(() => client.destroy()) | ||
client.setEncoding('utf8') | ||
client.write('Hello') | ||
}) | ||
client.setEncoding('utf8') | ||
client.write('Hello') | ||
await p | ||
}) | ||
test('Should gracefully close with a connected client', (t) => { | ||
t.plan(6) | ||
test('Should gracefully close with a connected client', async (t) => { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
fastify.register(fastifyWebsocket) | ||
await fastify.register(fastifyWebsocket) | ||
let serverConnEnded | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
connection.setEncoding('utf8') | ||
@@ -382,32 +389,25 @@ connection.write('hello client') | ||
connection.on('end', () => { | ||
t.pass('end emitted on server side') | ||
}) | ||
serverConnEnded = once(connection, 'end') | ||
// this connection stays alive untile we close the server | ||
}) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
client.setEncoding('utf8') | ||
client.write('hello server') | ||
client.on('end', () => { | ||
t.pass('end emitted on client side') | ||
}) | ||
const ended = once(client, 'end') | ||
client.once('data', (chunk) => { | ||
t.equal(chunk, 'hello client') | ||
fastify.close(function (err) { | ||
t.error(err) | ||
}) | ||
}) | ||
}) | ||
const [chunk] = await once(client, 'data') | ||
t.equal(chunk, 'hello client') | ||
await fastify.close() | ||
await ended | ||
await serverConnEnded | ||
}) | ||
test('Should gracefully close when clients attempt to connect after calling close', (t) => { | ||
t.plan(5) | ||
test('Should gracefully close when clients attempt to connect after calling close', async (t) => { | ||
t.plan(3) | ||
@@ -417,6 +417,7 @@ const fastify = Fastify() | ||
const oldClose = fastify.server.close | ||
let p | ||
fastify.server.close = function (cb) { | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
ws.on('close', () => { | ||
p = once(ws, 'close').then(() => { | ||
t.pass('client 2 closed') | ||
@@ -430,5 +431,5 @@ }) | ||
fastify.register(fastifyWebsocket) | ||
await fastify.register(fastifyWebsocket) | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
fastify.get('/', { websocket: true }, (connection) => { | ||
t.pass('received client connection') | ||
@@ -439,17 +440,13 @@ t.teardown(() => connection.destroy()) | ||
fastify.listen(0, (err) => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
const ws = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
ws.on('close', () => { | ||
t.pass('client 1 closed') | ||
}) | ||
ws.on('close', () => { | ||
t.pass('client 1 closed') | ||
}) | ||
ws.on('open', (chunk) => { | ||
fastify.close(function (err) { | ||
t.error(err) | ||
}) | ||
}) | ||
}) | ||
await once(ws, 'open') | ||
await fastify.close() | ||
await p | ||
}) | ||
@@ -464,4 +461,4 @@ | ||
*/ | ||
test('Should keep accepting connection', t => { | ||
t.plan(3) | ||
test('Should keep accepting connection', { skip: !timersPromises }, async t => { | ||
t.plan(1) | ||
@@ -473,6 +470,6 @@ const fastify = Fastify() | ||
fastify.register(fastifyWebsocket) | ||
await fastify.register(fastifyWebsocket) | ||
fastify.get('/', { websocket: true }, ({ socket }, request, reply) => { | ||
socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, ({ socket }) => { | ||
socket.on('message', () => { | ||
unhandled-- | ||
@@ -499,46 +496,37 @@ }) | ||
fastify.listen(0, err => { | ||
t.error(err) | ||
await fastify.listen({ port: 0 }) | ||
// Setup a client that sends a lot of messages to the server | ||
const client = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
// Setup a client that sends a lot of messages to the server | ||
const client = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
client.on('error', console.error) | ||
client.on('open', event => { | ||
const message = Buffer.alloc(1024, Date.now()) | ||
await once(client, 'open') | ||
const message = Buffer.alloc(1024, Date.now()) | ||
const interval = setInterval(() => { | ||
client.send(message.toString(), 10) | ||
sent++ | ||
unhandled++ | ||
if (sent === 50) { | ||
threshold = unhandled | ||
} else if (sent === 100) { | ||
clearInterval(interval) | ||
fastify.close(err => { | ||
t.error(err) | ||
t.ok(unhandled <= threshold) | ||
}) | ||
} | ||
}, 10) | ||
}) | ||
client.on('error', console.error) | ||
}) | ||
/* eslint-disable no-unused-vars */ | ||
for await (const _ of timersPromises.setInterval(10)) { | ||
client.send(message.toString(), 10) | ||
sent++ | ||
unhandled++ | ||
if (sent === 50) { | ||
threshold = unhandled | ||
} else if (sent === 100) { | ||
await fastify.close() | ||
t.ok(unhandled <= threshold) | ||
break | ||
} | ||
} | ||
}) | ||
test('Should keep processing message when many medium sized messages are sent', t => { | ||
t.plan(3) | ||
test('Should keep processing message when many medium sized messages are sent', async t => { | ||
t.plan(1) | ||
const fastify = Fastify() | ||
const total = 200 | ||
let safetyInterval | ||
let sent = 0 | ||
let handled = 0 | ||
fastify.register(fastifyWebsocket) | ||
await fastify.register(fastifyWebsocket) | ||
fastify.get('/', { websocket: true }, ({ socket }, req) => { | ||
socket.on('message', message => { | ||
fastify.get('/', { websocket: true }, ({ socket }) => { | ||
socket.on('message', () => { | ||
socket.send('handled') | ||
@@ -550,45 +538,27 @@ }) | ||
}) | ||
}) | ||
/* | ||
This is a safety check - If the socket is stuck, fastify.close will not run. | ||
*/ | ||
safetyInterval = setInterval(() => { | ||
if (sent < total) { | ||
return | ||
} | ||
await fastify.listen({ port: 0 }) | ||
t.fail('Forcibly closed.') | ||
// Setup a client that sends a lot of messages to the server | ||
const client = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
client.on('error', console.error) | ||
clearInterval(safetyInterval) | ||
socket.terminate() | ||
}, 100) | ||
}) | ||
await once(client, 'open') | ||
fastify.listen(0, err => { | ||
t.error(err) | ||
for (let i = 0; i < total; i++) { | ||
client.send(Buffer.alloc(160, `${i}`).toString('utf-8')) | ||
} | ||
// Setup a client that sends a lot of messages to the server | ||
const client = new WebSocket('ws://localhost:' + fastify.server.address().port) | ||
/* eslint-disable no-unused-vars */ | ||
for await (const _ of on(client, 'message')) { | ||
handled++ | ||
client.on('open', () => { | ||
for (let i = 0; i < total; i++) { | ||
client.send(Buffer.alloc(160, `${i}`).toString('utf-8')) | ||
sent++ | ||
} | ||
}) | ||
if (handled === total) { | ||
break | ||
} | ||
} | ||
client.on('message', message => { | ||
handled++ | ||
if (handled === total) { | ||
fastify.close(err => { | ||
clearInterval(safetyInterval) | ||
t.error(err) | ||
t.equal(handled, total) | ||
}) | ||
} | ||
}) | ||
client.on('error', console.error) | ||
}) | ||
await fastify.close() | ||
t.equal(handled, total) | ||
}) | ||
@@ -614,3 +584,3 @@ | ||
t.equal(fastify.prefix, '/hello') | ||
fastify.get('/', function (request, reply) { | ||
fastify.get('/', function (_, reply) { | ||
t.equal(this.prefix, '/hello') | ||
@@ -617,0 +587,0 @@ reply.send('hello') |
@@ -17,19 +17,21 @@ 'use strict' | ||
fastify.addHook('onRequest', async (request, reply) => t.ok('called', 'onRequest')) | ||
fastify.addHook('preParsing', async (request, reply, payload) => t.ok('called', 'preParsing')) | ||
fastify.addHook('preValidation', async (request, reply) => t.ok('called', 'preValidation')) | ||
fastify.addHook('preHandler', async (request, reply) => t.ok('called', 'preHandler')) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('onRequest', async (request, reply) => t.ok('called', 'onRequest')) | ||
fastify.addHook('preParsing', async (request, reply, payload) => t.ok('called', 'preParsing')) | ||
fastify.addHook('preValidation', async (request, reply) => t.ok('called', 'preValidation')) | ||
fastify.addHook('preHandler', async (request, reply) => t.ok('called', 'preHandler')) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
conn.once('data', chunk => { | ||
t.equal(chunk, 'hello server') | ||
conn.end() | ||
}) | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -58,12 +60,14 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('onTimeout', async (request, reply) => t.fail('called', 'onTimeout')) | ||
fastify.register(async function () { | ||
fastify.addHook('onTimeout', async (request, reply) => t.fail('called', 'onTimeout')) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
request.raw.setTimeout(50) | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
request.raw.setTimeout(50) | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -88,10 +92,12 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('onRequest', async (request, reply) => { throw new Error('Fail') }) | ||
fastify.addHook('onError', async (request, reply) => t.ok('called', 'onError')) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('onRequest', async (request, reply) => { throw new Error('Fail') }) | ||
fastify.addHook('onError', async (request, reply) => t.ok('called', 'onError')) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
}) | ||
fastify.listen(0, function (err) { | ||
fastify.listen({ port: 0 }, function (err) { | ||
t.error(err) | ||
@@ -113,14 +119,16 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
throw new Error('Fail') | ||
}) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
throw new Error('Fail') | ||
}) | ||
fastify.addHook('onError', async (request, reply) => t.ok('called', 'onError')) | ||
fastify.addHook('onError', async (request, reply) => t.ok('called', 'onError')) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
}) | ||
fastify.listen(0, function (err) { | ||
fastify.listen({ port: 0 }, function (err) { | ||
t.error(err) | ||
@@ -142,17 +150,19 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
throw new Error('Fail') | ||
}) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
throw new Error('Fail') | ||
}) | ||
fastify.addHook('onError', async (request, reply) => { | ||
t.ok('called', 'onError') | ||
await reply.code(404).send('there was an error') | ||
}) | ||
fastify.addHook('onError', async (request, reply) => { | ||
t.ok('called', 'onError') | ||
await reply.code(404).send('there was an error') | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
}) | ||
fastify.listen(0, function (err) { | ||
fastify.listen({ port: 0 }, function (err) { | ||
t.error(err) | ||
@@ -174,10 +184,12 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('onError', async (request, reply) => t.fail('called', 'onError')) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('onError', async (request, reply) => t.fail('called', 'onError')) | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
t.teardown(conn.destroy.bind(conn)) | ||
throw new Error('Fail') | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
t.teardown(conn.destroy.bind(conn)) | ||
throw new Error('Fail') | ||
}) | ||
}) | ||
fastify.listen(0, function (err) { | ||
fastify.listen({ port: 0 }, function (err) { | ||
t.error(err) | ||
@@ -199,13 +211,15 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.addHook('onSend', async (request, reply) => t.fail('called', 'onSend')) | ||
fastify.addHook('preSerialization', async (request, reply) => t.fail('called', 'preSerialization')) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('onSend', async (request, reply) => t.fail('called', 'onSend')) | ||
fastify.addHook('preSerialization', async (request, reply) => t.fail('called', 'preSerialization')) | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
conn.end() | ||
fastify.get('/echo', { websocket: true }, async (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
conn.end() | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -231,7 +245,9 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
fastify.get('/', async (request, reply) => { | ||
throw new Error('Fail') | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', async (request, reply) => { | ||
throw new Error('Fail') | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -248,2 +264,3 @@ | ||
}) | ||
httpClient.end() | ||
}) | ||
@@ -261,19 +278,21 @@ }) | ||
fastify.addHook( | ||
'preValidation', | ||
async () => await new Promise((resolve) => setTimeout(resolve, 25)) | ||
) | ||
fastify.register(async function (fastify) { | ||
fastify.addHook( | ||
'preValidation', | ||
async () => await new Promise((resolve) => setTimeout(resolve, 25)) | ||
) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
t.teardown(conn.destroy.bind(conn)) | ||
conn.socket.on('message', (message) => { | ||
t.equal(message.toString('utf-8'), 'hello server') | ||
conn.end() | ||
conn.socket.on('message', (message) => { | ||
t.equal(message.toString('utf-8'), 'hello server') | ||
conn.end() | ||
}) | ||
}) | ||
}) | ||
fastify.listen(0, (err) => { | ||
fastify.listen({ port: 0 }, (err) => { | ||
t.error(err) | ||
@@ -302,11 +321,13 @@ const ws = new WebSocket( | ||
fastify.register(fastifyWebsocket) | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
await reply.code(404).send('not found') | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
await reply.code(404).send('not found') | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -322,2 +343,3 @@ | ||
}) | ||
httpClient.end() | ||
}) | ||
@@ -330,22 +352,24 @@ }) | ||
const fastify = Fastify() | ||
t.teardown(() => fastify.close()) | ||
fastify.register(fastifyWebsocket) | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await Promise.resolve() | ||
await reply.code(404).send('not found') | ||
fastify.register(async function (fastify) { | ||
fastify.addHook('preValidation', async (request, reply) => { | ||
await reply.code(404).send('not found') | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
t.fail() | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo') | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }) | ||
t.teardown(client.destroy.bind(client)) | ||
client.on('error', error => t.ok(error)) | ||
ws.on('error', error => { | ||
t.ok(error) | ||
ws.close() | ||
fastify.close() | ||
}) | ||
}) | ||
}) |
@@ -35,3 +35,3 @@ 'use strict' | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -76,3 +76,3 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/baz/echo') | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -124,3 +124,3 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/baz') | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -161,21 +161,23 @@ const url = '//localhost:' + (fastify.server.address()).port + '/baz/echo' | ||
fastify.register(fastifyWebsocket) | ||
fastify | ||
.register(fastifyWebsocket) | ||
.register(async function () { | ||
fastify.get('/*', (request, reply) => { | ||
reply.send('hello world') | ||
}) | ||
fastify.get('/*', (request, reply) => { | ||
reply.send('hello world') | ||
}) | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
}) | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -197,21 +199,23 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port) | ||
fastify.register(fastifyWebsocket) | ||
fastify | ||
.register(fastifyWebsocket) | ||
.register(async function (fastify) { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/*', | ||
handler: (_, reply) => { | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: (conn) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/*', | ||
handler: (req, reply) => { | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: (conn, req) => { | ||
conn.setEncoding('utf8') | ||
conn.write('hello client') | ||
conn.once('data', chunk => { | ||
conn.end() | ||
conn.once('data', () => { | ||
conn.end() | ||
}) | ||
} | ||
}) | ||
} | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -235,18 +239,19 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port) | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
conn.socket.on('message', message => { | ||
try { | ||
conn.socket.send('hi from wildcard route handler') | ||
} catch (err) { | ||
conn.socket.send(err.message) | ||
} | ||
fastify | ||
.register(fastifyWebsocket) | ||
.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn) => { | ||
conn.socket.on('message', () => { | ||
try { | ||
conn.socket.send('hi from wildcard route handler') | ||
} catch (err) { | ||
conn.socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
}) | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
fastify.get('/echo', { websocket: true }, (conn, request) => { | ||
conn.socket.on('message', message => { | ||
fastify.get('/echo', { websocket: true }, (conn) => { | ||
conn.socket.on('message', () => { | ||
try { | ||
@@ -262,3 +267,3 @@ conn.socket.send('hi from /echo handler') | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -291,15 +296,17 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port) | ||
fastify.register(fastifyWebsocket) | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/', | ||
handler: (request, reply) => { | ||
reply.send('hi from handler') | ||
}, | ||
wsHandler: (conn, request) => { | ||
conn.write('hi from wsHandler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
} | ||
fastify.register(async function () { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/', | ||
handler: (request, reply) => { | ||
reply.send('hi from handler') | ||
}, | ||
wsHandler: (conn, request) => { | ||
conn.write('hi from wsHandler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
} | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -328,3 +335,2 @@ | ||
test('Should call the wildcard handler if a no other non-websocket route with path exists', t => { | ||
t.plan(2) | ||
const fastify = Fastify() | ||
@@ -335,13 +341,16 @@ t.teardown(() => fastify.close()) | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
t.ok('called', 'wildcard handler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
t.ok('called', 'wildcard handler') | ||
conn.end() | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
fastify.get('/http', (request, reply) => { | ||
t.fail('Should not call http handler') | ||
reply.send('http route') | ||
fastify.get('/http', (request, reply) => { | ||
t.fail('Should not call http handler') | ||
reply.send('http route') | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -363,14 +372,15 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/http2') | ||
fastify.register(fastifyWebsocket) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
t.fail('called', 'wildcard handler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
}) | ||
fastify.get('/*', { websocket: true }, (conn, request) => { | ||
t.fail('called', 'wildcard handler') | ||
t.teardown(conn.destroy.bind(conn)) | ||
fastify.get('/http', (request, reply) => { | ||
t.fail('Should not call /http handler') | ||
reply.send('http route') | ||
}) | ||
}) | ||
fastify.get('/http', (request, reply) => { | ||
t.fail('Should not call /http handler') | ||
reply.send('http route') | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -392,14 +402,21 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/http') | ||
fastify.register(fastifyWebsocket) | ||
fastify.register(async function (fastify) { | ||
fastify.post('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
fastify.post('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
fastify.get('/http', (request, reply) => { | ||
t.fail('Should not call /http handler') | ||
reply.send('http route') | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
fastify.listen(0, (err) => { | ||
fastify.listen({ port: 0 }, (err) => { | ||
t.ok(err) | ||
@@ -410,4 +427,4 @@ t.equal(err.message, 'websocket handler can only be declared in GET method') | ||
test('Should throw on invalid wsHandler', t => { | ||
t.plan(2) | ||
test('Should throw on invalid wsHandler', async t => { | ||
t.plan(1) | ||
const fastify = Fastify() | ||
@@ -417,17 +434,15 @@ | ||
fastify.register(fastifyWebsocket) | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/echo', | ||
handler: (request, reply) => { | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: 'hello' | ||
}, | ||
{ prefix: '/baz' }) | ||
fastify.listen(0, err => { | ||
t.ok(err) | ||
await fastify.register(fastifyWebsocket) | ||
try { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/echo', | ||
handler: (_, reply) => { | ||
reply.send({ hello: 'world' }) | ||
}, | ||
wsHandler: 'hello' | ||
}, { prefix: '/baz' }) | ||
} catch (err) { | ||
t.equal(err.message, 'invalid wsHandler function') | ||
}) | ||
} | ||
}) | ||
@@ -443,15 +458,17 @@ | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
fastify.register(async function (fastify) { | ||
fastify.get('/echo', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
try { | ||
connection.socket.send(message) | ||
} catch (err) { | ||
connection.socket.send(err.message) | ||
} | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -477,16 +494,18 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/echo/') | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
}) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
}) | ||
connection.socket.on('close', () => { | ||
t.pass() | ||
connection.socket.on('close', () => { | ||
t.pass() | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -518,14 +537,15 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/') | ||
fastify.register(fastifyWebsocket) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
}) | ||
fastify.get('/', { websocket: true }, (connection, request) => { | ||
connection.socket.on('message', message => { | ||
t.equal(message.toString(), 'hi from client') | ||
connection.socket.send('hi from server') | ||
}) | ||
connection.socket.on('close', () => { | ||
t.pass() | ||
}) | ||
connection.socket.on('close', () => { | ||
t.pass() | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
t.teardown(connection.destroy.bind(connection)) | ||
}) | ||
@@ -549,16 +569,18 @@ | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', { websocket: true }, (conn, request) => { | ||
const params = request.params | ||
t.equal(Object.keys(params).length, 0, 'params are empty') | ||
conn.write('empty') | ||
conn.end() | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, (conn, request) => { | ||
const params = request.params | ||
t.equal(Object.keys(params).length, 0, 'params are empty') | ||
conn.write('empty') | ||
conn.end() | ||
}) | ||
fastify.get('/ws/:id', { websocket: true }, (conn, request) => { | ||
const params = request.params | ||
t.equal(params.id, 'foo', 'params are correct') | ||
conn.write(params.id) | ||
conn.end() | ||
}) | ||
}) | ||
fastify.get('/ws/:id', { websocket: true }, (conn, request) => { | ||
const params = request.params | ||
t.equal(params.id, 'foo', 'params are correct') | ||
conn.write(params.id) | ||
conn.end() | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
let pending = 2 | ||
@@ -613,3 +635,3 @@ t.error(err) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
if (err) t.error(err) | ||
@@ -635,9 +657,11 @@ | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn, request) { | ||
t.equal(this, fastify, 'this is bound to fastify server') | ||
conn.write('empty') | ||
conn.end() | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn) { | ||
t.equal(this, fastify, 'this is bound to fastify server') | ||
conn.write('empty') | ||
conn.end() | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -667,9 +691,11 @@ const ws = new WebSocket( | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn, request) { | ||
t.equal(request.str, 'it works!', 'decorator is accessible') | ||
conn.write('empty') | ||
conn.end() | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, function wsHandler (conn, request) { | ||
t.equal(request.str, 'it works!', 'decorator is accessible') | ||
conn.write('empty') | ||
conn.end() | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -695,11 +721,13 @@ const ws = new WebSocket('ws://localhost:' + (fastify.server.address()).port + '/ws') | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', { websocket: true }, async function wsHandler (conn, request) { | ||
conn.on('error', err => { | ||
t.equal(err.message, 'something wrong') | ||
t.end() | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', { websocket: true }, async function wsHandler (conn, request) { | ||
conn.on('error', err => { | ||
t.equal(err.message, 'something wrong') | ||
t.end() | ||
}) | ||
throw new Error('something wrong') | ||
}) | ||
throw new Error('something wrong') | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -723,7 +751,9 @@ const ws = new WebSocket( | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', function handler (request, reply) { | ||
reply.send({ hello: 'world' }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', function handler (request, reply) { | ||
reply.send({ hello: 'world' }) | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -744,7 +774,9 @@ get('http://localhost:' + (fastify.server.address()).port + '/wrong-route', function (response) { | ||
fastify.register(fastifyWebsocket) | ||
fastify.get('/ws', function handler (request, reply) { | ||
reply.send({ hello: 'world' }) | ||
fastify.register(async function (fastify) { | ||
fastify.get('/ws', function handler (request, reply) { | ||
reply.send({ hello: 'world' }) | ||
}) | ||
}) | ||
fastify.listen(0, err => { | ||
fastify.listen({ port: 0 }, err => { | ||
t.error(err) | ||
@@ -751,0 +783,0 @@ get('http://localhost:' + (fastify.server.address()).port + '/ws', function (response) { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
75189
1704
274
6