From e95e07e4269f31e074ce00e48b95dfe83019d463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Pa=C3=9F?= <22845248+mpass99@users.noreply.github.com> Date: Thu, 9 Dec 2021 10:02:26 +0100 Subject: [PATCH] Catch the client connection "Close normal" error * Catch the client connection "Close normal" error * Reduce cognitive complexity of the input read loop --- internal/api/websocket.go | 51 ++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/internal/api/websocket.go b/internal/api/websocket.go index bffba0d..ca1bfaa 100644 --- a/internal/api/websocket.go +++ b/internal/api/websocket.go @@ -76,31 +76,42 @@ func (cr *codeOceanToRawReader) readInputLoop(ctx context.Context) { case <-readMessage: } - if err != nil { - log.WithField("remote", cr.connection.(*websocket.Conn).UnderlyingConn().RemoteAddr()). - WithError(err).Warn("Error reading client message") + if handleInput(messageType, reader, err, cr.buffer, ctx) { return } - if messageType != websocket.TextMessage { - log.WithField("messageType", messageType).Warn("Received message of wrong type") - return - } - - message, err := io.ReadAll(reader) - if err != nil { - log.WithError(err).Warn("error while reading WebSocket message") - return - } - for _, character := range message { - select { - case <-ctx.Done(): - return - case cr.buffer <- character: - } - } } } +// handleInput receives a new message from the client and may forward it to the executor. +func handleInput(messageType int, reader io.Reader, err error, buffer chan byte, ctx context.Context) (done bool) { + if err != nil && websocket.IsCloseError(err, websocket.CloseNormalClosure) { + log.Debug("ReadInputLoop: The client closed the connection!") + // The close handler will do something soon. + return true + } else if err != nil { + log.WithError(err).Warn("Error reading client message") + return true + } + if messageType != websocket.TextMessage { + log.WithField("messageType", messageType).Warn("Received message of wrong type") + return true + } + + message, err := io.ReadAll(reader) + if err != nil { + log.WithError(err).Warn("error while reading WebSocket message") + return true + } + for _, character := range message { + select { + case <-ctx.Done(): + return true + case buffer <- character: + } + } + return false +} + // startReadInputLoop start the read input loop asynchronously and returns a context.CancelFunc which can be used // to cancel the read input loop. func (cr *codeOceanToRawReader) startReadInputLoop() context.CancelFunc {