From bad536e9d099811e828cb77b843b632286569685 Mon Sep 17 00:00:00 2001 From: Nicko Guyer Date: Tue, 26 Oct 2021 17:11:33 -0400 Subject: [PATCH 1/3] Add check before writing to websocket channel Signed-off-by: Nicko Guyer --- .../events/websockets/websocket_connection.go | 3 +++ internal/events/websockets/websockets_test.go | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/internal/events/websockets/websocket_connection.go b/internal/events/websockets/websocket_connection.go index 9f69a13f4..c8b4fd6af 100644 --- a/internal/events/websockets/websocket_connection.go +++ b/internal/events/websockets/websocket_connection.go @@ -223,6 +223,9 @@ func (wc *websocketConnection) protocolError(err error) { } func (wc *websocketConnection) send(msg interface{}) error { + if wc.closed { + return i18n.NewError(wc.ctx, i18n.MsgWSClosing) // TODO: set to "closed" + } select { case wc.sendMessages <- msg: return nil diff --git a/internal/events/websockets/websockets_test.go b/internal/events/websockets/websockets_test.go index 0ddbd6dd1..44440f6e5 100644 --- a/internal/events/websockets/websockets_test.go +++ b/internal/events/websockets/websockets_test.go @@ -606,3 +606,27 @@ func TestDispatchAutoAck(t *testing.T) { assert.NoError(t, err) cbs.AssertExpectations(t) } + +func TestWebsocketSendAfterClose(t *testing.T) { + cbs := &eventsmocks.Callbacks{} + ws, wsc, cancel := newTestWebsockets(t, cbs) + defer cancel() + + subscribedConn := make(chan string, 1) + cbs.On("EphemeralSubscription", + mock.MatchedBy(func(s string) bool { + subscribedConn <- s + return true + }), + "ns1", mock.Anything, mock.Anything).Return(nil) + + err := wsc.Send(context.Background(), []byte(`{"type":"start","namespace":"ns1","ephemeral":true}`)) + assert.NoError(t, err) + + connID := <-subscribedConn + connection := ws.connections[connID] + connection.wsConn.Close() + <-connection.senderDone + err = connection.send(map[string]string{"foo": "bar"}) + assert.Regexp(t, "FF10160", err) +} From 1c0695ac6c5a316ccc4b78c5266b54262c336dc8 Mon Sep 17 00:00:00 2001 From: Nicko Guyer Date: Thu, 28 Oct 2021 10:26:39 -0400 Subject: [PATCH 2/3] Add websocket closed error message Signed-off-by: Nicko Guyer --- internal/events/websockets/websocket_connection.go | 2 +- internal/i18n/en_translations.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/events/websockets/websocket_connection.go b/internal/events/websockets/websocket_connection.go index c8b4fd6af..79dc29687 100644 --- a/internal/events/websockets/websocket_connection.go +++ b/internal/events/websockets/websocket_connection.go @@ -224,7 +224,7 @@ func (wc *websocketConnection) protocolError(err error) { func (wc *websocketConnection) send(msg interface{}) error { if wc.closed { - return i18n.NewError(wc.ctx, i18n.MsgWSClosing) // TODO: set to "closed" + return i18n.NewError(wc.ctx, i18n.MsgWSClosed) } select { case wc.sendMessages <- msg: diff --git a/internal/i18n/en_translations.go b/internal/i18n/en_translations.go index 681c22684..4cfe2365f 100644 --- a/internal/i18n/en_translations.go +++ b/internal/i18n/en_translations.go @@ -206,4 +206,5 @@ var ( MsgFailedToDecodeCertificate = ffm("FF10286", "Failed to decode certificate: %s", 500) MsgInvalidMessageType = ffm("FF10287", "Invalid message type - allowed types are %s", 400) MsgNoUUID = ffm("FF10288", "Field '%s' must not be a UUID", 400) + MsgWSClosed = ffm("FF10289", "Websocket closed") ) From d80703fea5f98c04034698be984b613689d19778 Mon Sep 17 00:00:00 2001 From: Nicko Guyer Date: Thu, 28 Oct 2021 10:38:56 -0400 Subject: [PATCH 3/3] Fix unit test to look for new error code Signed-off-by: Nicko Guyer --- internal/events/websockets/websockets_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/events/websockets/websockets_test.go b/internal/events/websockets/websockets_test.go index 44440f6e5..59eb97f9a 100644 --- a/internal/events/websockets/websockets_test.go +++ b/internal/events/websockets/websockets_test.go @@ -628,5 +628,5 @@ func TestWebsocketSendAfterClose(t *testing.T) { connection.wsConn.Close() <-connection.senderDone err = connection.send(map[string]string{"foo": "bar"}) - assert.Regexp(t, "FF10160", err) + assert.Regexp(t, "FF10290", err) }