Skip to content

Fix: Initial messages could be lost #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions hapi-plugin-websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,10 @@ const register = async (server, pluginOptions) => {
delete headers["accept-encoding"]

/* optionally inject an empty initial message */
let initially;
if (routeOptions.initially) {
/* inject incoming WebSocket message as a simulated HTTP request */
const response = await server.inject({
initially = server.inject({
/* simulate the hard-coded POST request */
method: "POST",

Expand All @@ -233,25 +234,32 @@ const register = async (server, pluginOptions) => {
plugins: {
websocket: { mode: "websocket", ctx, wss, ws, wsf, req, peers, initially: true }
}
})

/* any HTTP redirection, client error or server error response
leads to an immediate WebSocket connection drop */
if (response.statusCode >= 300) {
const annotation = `(HAPI handler responded with HTTP status ${response.statusCode})`
if (response.statusCode < 400)
ws.close(1002, `Protocol Error ${annotation}`)
else if (response.statusCode < 500)
ws.close(1008, `Policy Violation ${annotation}`)
else
ws.close(1011, `Server Error ${annotation}`)
}
}).then(response => {
/* any HTTP redirection, client error or server error response
leads to an immediate WebSocket connection drop */
if (response.statusCode < 300) {
return true;
} else {
const annotation = `(HAPI handler responded with HTTP status ${response.statusCode})`
if (response.statusCode < 400)
ws.close(1002, `Protocol Error ${annotation}`)
else if (response.statusCode < 500)
ws.close(1008, `Policy Violation ${annotation}`)
else
ws.close(1011, `Server Error ${annotation}`)
return false;
}
});
}

/* hook into WebSocket message retrieval */
if (routeOptions.frame === true) {
/* framed WebSocket communication (correlated request/reply) */
wsf.on("message", async (ev) => {
if (initially && !(await initially)) {
return;
}

/* allow application to hook into raw WebSocket frame processing */
routeOptions.frameMessage.call(ctx, { ctx, wss, ws, wsf, req, peers }, ev.frame)

Expand Down Expand Up @@ -294,6 +302,10 @@ const register = async (server, pluginOptions) => {
else {
/* plain WebSocket communication (uncorrelated request/response) */
ws.on("message", async (message) => {
if (initially && !(await initially)) {
return;
}

/* inject incoming WebSocket message as a simulated HTTP request */
const response = await server.inject({
/* simulate the hard-coded POST request */
Expand Down Expand Up @@ -322,6 +334,7 @@ const register = async (server, pluginOptions) => {
/* hook into WebSocket disconnection */
ws.on("close", () => {
/* allow application to hook into WebSocket disconnection */
/* note that this is done even if the `initially` handler closes the connection */
routeOptions.disconnect.call(ctx, { ctx, wss, ws, wsf, req, peers })

/* stop tracking the peer */
Expand All @@ -330,6 +343,7 @@ const register = async (server, pluginOptions) => {
})

/* allow application to hook into WebSocket error processing */
/* note that this is done even if the `initially` handler closes the connection */
ws.on("error", (error) => {
routeOptions.error.call(ctx, { ctx, wss, ws, wsf, req, peers }, error)
})
Expand Down