Skip to content

NPE on trying to read uri, headers or attributes from the original HttpServletRequest wrapped in UpgradeRequest on WebSocket server in Jetty 12 #11294

@samfrown

Description

@samfrown

Jetty version(s)
Jetty 12.0.5

Jetty Environment
jetty-core, jetty-ee10

Java version/vendor (use: java -version)
openjdk 21 2023-09-19 LTS
OpenJDK Runtime Environment Corretto-21.0.0.35.1 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.0.35.1 (build 21+35-LTS, mixed mode, sharing)

OS type/version
Linux and MacOS

Description
I've migrated an application service from jetty 11.x to 12.x and faced an issue with WebSocket.
The server-side part on WebSocketOpen gets some headers and attributes from the HttpServletRequest wrapped into UpgradeRequest, like

public void onWebSocketOpen(Session sess)
    {
        this.session = sess;
        if (sess.getUpgradeRequest() instanceof JettyServerUpgradeRequest) {
            String path = ((JettyServerUpgradeRequest) sess.getUpgradeRequest()).getHttpServletRequest().getRequestURI();
            LOG.debug("Endpoint open: {}, path: {}", sess, path);
            var attrs1 = ((JettyServerUpgradeRequest) sess.getUpgradeRequest()).getServletAttributes().keySet();
            LOG.debug("Attrs1: {}", attrs1);
            var attrs2 = ((JettyServerUpgradeRequest) sess.getUpgradeRequest()).getHttpServletRequest().getAttributeNames();
            LOG.debug("Attrs2: {}", Collections.list(attrs2));
        } else {
            LOG.debug("Endpoint open: {}", sess);
        }
    }

The getHttpServletRequest() returns an instance of servlet request here
but throws an NPE on either getServletAttributes() or getHttpServletRequest().getAttribute(...) or getHttpServletRequest().getRequestUri(), because "org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequest()" is null like:

org.eclipse.jetty.websocket.api.exceptions.CloseException: org.eclipse.jetty.websocket.core.exception.WebSocketException: EventEndpoint OPEN method error: Cannot invoke "org.eclipse.jetty.server.Request.getHttpURI()" because the return value of "org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequest()" is null
	at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.convertCause(JettyWebSocketFrameHandler.java:425)
	at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onError(JettyWebSocketFrameHandler.java:239)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.lambda$closeConnection$2(WebSocketCoreSession.java:271)
	at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1202)
	at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1195)
	at org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker$1.handle(AbstractHandshaker.java:179)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.closeConnection(WebSocketCoreSession.java:271)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.lambda$sendFrame$7(WebSocketCoreSession.java:492)
	at org.eclipse.jetty.util.Callback$3.succeeded(Callback.java:162)
	at org.eclipse.jetty.websocket.core.util.TransformingFlusher.notifyCallbackSuccess(TransformingFlusher.java:195)
	at org.eclipse.jetty.websocket.core.util.TransformingFlusher$Flusher.process(TransformingFlusher.java:152)
	at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:250)
	at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:231)
	at org.eclipse.jetty.websocket.core.util.TransformingFlusher.sendFrame(TransformingFlusher.java:78)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.sendFrame(WebSocketCoreSession.java:495)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.close(WebSocketCoreSession.java:223)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.processHandlerError(WebSocketCoreSession.java:354)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.lambda$onOpen$5(WebSocketCoreSession.java:385)
	at org.eclipse.jetty.util.Callback$3.failed(Callback.java:168)
	at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onOpen(JettyWebSocketFrameHandler.java:151)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.lambda$onOpen$6(WebSocketCoreSession.java:391)
	at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1208)
	at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.run(ContextHandler.java:1195)
	at org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker$1.handle(AbstractHandshaker.java:179)
	at org.eclipse.jetty.websocket.core.WebSocketCoreSession.onOpen(WebSocketCoreSession.java:391)
	at org.eclipse.jetty.websocket.core.WebSocketConnection.onOpen(WebSocketConnection.java:544)
	at org.eclipse.jetty.io.AbstractEndPoint.upgrade(AbstractEndPoint.java:435)
	at org.eclipse.jetty.server.internal.HttpConnection$HttpStreamOverHTTP1.succeeded(HttpConnection.java:1513)
	at org.eclipse.jetty.server.HttpStream$Wrapper.succeeded(HttpStream.java:221)
	at org.eclipse.jetty.server.internal.CompletionStreamWrapper.succeeded(CompletionStreamWrapper.java:45)
	at org.eclipse.jetty.server.HttpStream$Wrapper.succeeded(HttpStream.java:221)
	at org.eclipse.jetty.session.AbstractSessionManager$SessionStreamWrapper.succeeded(AbstractSessionManager.java:1465)
	at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.completeStream(HttpChannelState.java:699)
	at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:629)
	at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:424)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:99)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:971)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1201)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1156)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.eclipse.jetty.websocket.core.exception.CloseException: org.eclipse.jetty.websocket.core.exception.WebSocketException: EventEndpoint OPEN method error: Cannot invoke "org.eclipse.jetty.server.Request.getHttpURI()" because the return value of "org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequest()" is null
	... 25 more
Caused by: org.eclipse.jetty.websocket.core.exception.WebSocketException: EventEndpoint OPEN method error: Cannot invoke "org.eclipse.jetty.server.Request.getHttpURI()" because the return value of "org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequest()" is null
	... 23 more
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.jetty.server.Request.getHttpURI()" because the return value of "org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequest()" is null
	at org.eclipse.jetty.ee10.servlet.ServletApiRequest.getRequestURI(ServletApiRequest.java:371)
	at org.eclipse.jetty.demo.EventEndpoint.onWebSocketOpen(EventEndpoint.java:43)
	at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.onOpen(JettyWebSocketFrameHandler.java:142)
	... 22 more

How to reproduce?

It can be reproduced with the sample server from: https://github.com/jetty-project/embedded-jetty-websocket-examples/blob/638ed97c30a81345dc160d1348191eb50d0d6875/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo/EventEndpoint.java#L36
with just adding sample code from the 'Description' above.

Metadata

Metadata

Labels

BugFor general bugs on Jetty sideStaleFor auto-closed stale issues and pull requests

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions