This is an automated email from the ASF dual-hosted git repository.
Arsnael pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 274f65f94d [ENHANCEMENT] Prevent verbose logs when WS client
disconnect during handshake
274f65f94d is described below
commit 274f65f94ddcae706d1d1017fe8d6afefb2daee5
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Sep 25 15:43:28 2026 +0200
[ENHANCEMENT] Prevent verbose logs when WS client disconnect during
handshake
Solves this:
java.lang.NullPointerException: Cannot invoke
"java.lang.Boolean.booleanValue()" because the return value of
"io.netty.util.Attribute.get()" is null
at reactor.netty.Connection.isPersistent(Connection.java:248)
at
reactor.netty.channel.ChannelOperations.isPersistent(ChannelOperations.java:607)
at
reactor.netty.ReactorNetty.addHandlerBeforeReactorEndHandlers(ReactorNetty.java:390)
at reactor.netty.Connection.addHandlerLast(Connection.java:165)
at
reactor.netty.http.websocket.WebsocketInbound.lambda$aggregateFrames$0(WebsocketInbound.java:86)
at
reactor.netty.http.server.HttpServerOperations.withConnection(HttpServerOperations.java:250)
at
reactor.netty.http.server.HttpServerOperations.withConnection(HttpServerOperations.java:124)
at
reactor.netty.http.websocket.WebsocketInbound.aggregateFrames(WebsocketInbound.java:86)
at
reactor.netty.http.websocket.WebsocketInbound.aggregateFrames(WebsocketInbound.java:74)
at
org.apache.james.jmap.routes.WebSocketRoutes.handleWebSocketConnection(WebSocketRoutes.scala:119)
---
.../apache/james/jmap/routes/WebSocketRoutes.scala | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala
index fa8f92f09f..68e4998c3f 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala
@@ -20,7 +20,7 @@
package org.apache.james.jmap.routes
import java.nio.charset.StandardCharsets
-import java.util.concurrent.atomic.AtomicReference
+import java.util.concurrent.atomic.{AtomicBoolean, AtomicReference}
import java.util.function.Predicate
import java.util.{Optional, stream}
@@ -107,7 +107,7 @@ class WebSocketRoutes @Inject()
(@Named(InjectionKeys.RFC_8621) val authenticato
.`then`
.`then`(SMono(httpServerResponse.addHeader(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL,
"jmap")
.sendWebsocket((in: WebsocketInbound, out: WebsocketOutbound) =>
handleWebSocketConnection(mailboxSession)(in, out), websocketServerSpec))))
- .onErrorResume(throwable => handleHttpHandshakeError(throwable,
httpServerResponse))
+ .onErrorResume(throwable => handleHttpHandshakeError(throwable,
httpServerRequest, httpServerResponse))
.asJava()
.`then`()
@@ -196,9 +196,21 @@ class WebSocketRoutes @Inject()
(@Named(InjectionKeys.RFC_8621) val authenticato
})
}
- private def handleHttpHandshakeError(throwable: Throwable, response:
HttpServerResponse): SMono[Void] = throwable match {
- case e: UnauthorizedException => respondDetails(e.addHeaders(response),
ProblemDetails.forThrowable(throwable))
- case _ => respondDetails(response, ProblemDetails.forThrowable(throwable))
+ private def handleHttpHandshakeError(throwable: Throwable, request:
HttpServerRequest, response: HttpServerResponse): SMono[Void] =
+ if (isClientDisconnected(request)) {
+ WebSocketRoutes.LOGGER.info("Client disconnected during WebSocket
handshake: {}", throwable.getMessage)
+ SMono.empty
+ } else {
+ throwable match {
+ case e: UnauthorizedException =>
respondDetails(e.addHeaders(response), ProblemDetails.forThrowable(throwable))
+ case _ => respondDetails(response,
ProblemDetails.forThrowable(throwable))
+ }
+ }
+
+ private def isClientDisconnected(request: HttpServerRequest): Boolean = {
+ val disconnected = new AtomicBoolean(false)
+ request.withConnection(connection =>
disconnected.set(connection.isDisposed || !connection.channel().isActive))
+ disconnected.get()
}
private def asError(requestId: Option[RequestId])(throwable: Throwable):
WebSocketError =
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]