Skip to content

Commit 1b31d39

Browse files
committed
Avoid hard reference to org.xnio.StreamConnection through reflection
Issue: SPR-13529
1 parent bb4e682 commit 1b31d39

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

spring-websocket/src/main/java/org/springframework/web/socket/server/standard/UndertowRequestUpgradeStrategy.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package org.springframework.web.socket.server.standard;
1818

1919
import java.lang.reflect.Constructor;
20+
import java.lang.reflect.InvocationHandler;
2021
import java.lang.reflect.Method;
22+
import java.lang.reflect.Proxy;
2123
import java.util.Arrays;
2224
import java.util.Collections;
2325
import java.util.List;
@@ -31,7 +33,6 @@
3133
import javax.websocket.Extension;
3234
import javax.websocket.server.ServerEndpointConfig;
3335

34-
import io.undertow.server.HttpServerExchange;
3536
import io.undertow.server.HttpUpgradeListener;
3637
import io.undertow.servlet.api.InstanceFactory;
3738
import io.undertow.servlet.api.InstanceHandle;
@@ -50,7 +51,6 @@
5051
import io.undertow.websockets.jsr.handshake.JsrHybi08Handshake;
5152
import io.undertow.websockets.jsr.handshake.JsrHybi13Handshake;
5253
import io.undertow.websockets.spi.WebSocketHttpExchange;
53-
import org.xnio.StreamConnection;
5454

5555
import org.springframework.http.server.ServerHttpRequest;
5656
import org.springframework.http.server.ServerHttpResponse;
@@ -122,8 +122,7 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat
122122

123123
// Adapting between different Pool API types in Undertow 1.0-1.2 vs 1.3
124124
getBufferPoolMethod = WebSocketHttpExchange.class.getMethod("getBufferPool");
125-
createChannelMethod = Handshake.class.getMethod("createChannel",
126-
WebSocketHttpExchange.class, StreamConnection.class, getBufferPoolMethod.getReturnType());
125+
createChannelMethod = ReflectionUtils.findMethod(Handshake.class, "createChannel", (Class<?>[]) null);
127126
}
128127
catch (Throwable ex) {
129128
throw new IllegalStateException("Incompatible Undertow API version", ex);
@@ -162,31 +161,39 @@ protected void upgradeInternal(ServerHttpRequest request, ServerHttpResponse res
162161

163162
HttpServletRequest servletRequest = getHttpServletRequest(request);
164163
HttpServletResponse servletResponse = getHttpServletResponse(response);
165-
166164
final ServletWebSocketHttpExchange exchange = createHttpExchange(servletRequest, servletResponse);
167165
exchange.putAttachment(HandshakeUtil.PATH_PARAMS, Collections.<String, String>emptyMap());
168166

169167
ServerWebSocketContainer wsContainer = (ServerWebSocketContainer) getContainer(servletRequest);
170168
final EndpointSessionHandler endpointSessionHandler = new EndpointSessionHandler(wsContainer);
171-
172169
final ConfiguredServerEndpoint configuredServerEndpoint = createConfiguredServerEndpoint(
173170
selectedProtocol, selectedExtensions, endpoint, servletRequest);
174-
175171
final Handshake handshake = getHandshakeToUse(exchange, configuredServerEndpoint);
176172

177-
exchange.upgradeChannel(new HttpUpgradeListener() {
178-
@Override
179-
public void handleUpgrade(StreamConnection connection, HttpServerExchange serverExchange) {
180-
Object bufferPool = ReflectionUtils.invokeMethod(getBufferPoolMethod, exchange);
181-
WebSocketChannel channel = (WebSocketChannel) ReflectionUtils.invokeMethod(
182-
createChannelMethod, handshake, exchange, connection, bufferPool);
183-
if (peerConnections != null) {
184-
peerConnections.add(channel);
185-
}
186-
endpointSessionHandler.onConnect(exchange, channel);
187-
}
188-
});
189-
173+
HttpUpgradeListener upgradeListener = (HttpUpgradeListener) Proxy.newProxyInstance(
174+
getClass().getClassLoader(), new Class<?>[] {HttpUpgradeListener.class},
175+
new InvocationHandler() {
176+
@Override
177+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
178+
if ("handleUpgrade".equals(method.getName())) {
179+
Object connection = args[0]; // currently an XNIO StreamConnection
180+
Object bufferPool = ReflectionUtils.invokeMethod(getBufferPoolMethod, exchange);
181+
WebSocketChannel channel = (WebSocketChannel) ReflectionUtils.invokeMethod(
182+
createChannelMethod, handshake, exchange, connection, bufferPool);
183+
if (peerConnections != null) {
184+
peerConnections.add(channel);
185+
}
186+
endpointSessionHandler.onConnect(exchange, channel);
187+
return null;
188+
}
189+
else {
190+
// any java.lang.Object method: equals, hashCode, toString...
191+
return ReflectionUtils.invokeMethod(method, this, args);
192+
}
193+
}
194+
});
195+
196+
exchange.upgradeChannel(upgradeListener);
190197
handshake.handshake(exchange);
191198
}
192199

0 commit comments

Comments
 (0)