Avoid hard reference to org.xnio.StreamConnection through reflection
Issue: SPR-13529
This commit is contained in:
parent
bb4e682a7e
commit
1b31d39b60
|
|
@ -17,7 +17,9 @@
|
||||||
package org.springframework.web.socket.server.standard;
|
package org.springframework.web.socket.server.standard;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -31,7 +33,6 @@ import javax.websocket.Endpoint;
|
||||||
import javax.websocket.Extension;
|
import javax.websocket.Extension;
|
||||||
import javax.websocket.server.ServerEndpointConfig;
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import io.undertow.server.HttpUpgradeListener;
|
import io.undertow.server.HttpUpgradeListener;
|
||||||
import io.undertow.servlet.api.InstanceFactory;
|
import io.undertow.servlet.api.InstanceFactory;
|
||||||
import io.undertow.servlet.api.InstanceHandle;
|
import io.undertow.servlet.api.InstanceHandle;
|
||||||
|
|
@ -50,7 +51,6 @@ import io.undertow.websockets.jsr.handshake.JsrHybi07Handshake;
|
||||||
import io.undertow.websockets.jsr.handshake.JsrHybi08Handshake;
|
import io.undertow.websockets.jsr.handshake.JsrHybi08Handshake;
|
||||||
import io.undertow.websockets.jsr.handshake.JsrHybi13Handshake;
|
import io.undertow.websockets.jsr.handshake.JsrHybi13Handshake;
|
||||||
import io.undertow.websockets.spi.WebSocketHttpExchange;
|
import io.undertow.websockets.spi.WebSocketHttpExchange;
|
||||||
import org.xnio.StreamConnection;
|
|
||||||
|
|
||||||
import org.springframework.http.server.ServerHttpRequest;
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
import org.springframework.http.server.ServerHttpResponse;
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
|
@ -122,8 +122,7 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat
|
||||||
|
|
||||||
// Adapting between different Pool API types in Undertow 1.0-1.2 vs 1.3
|
// Adapting between different Pool API types in Undertow 1.0-1.2 vs 1.3
|
||||||
getBufferPoolMethod = WebSocketHttpExchange.class.getMethod("getBufferPool");
|
getBufferPoolMethod = WebSocketHttpExchange.class.getMethod("getBufferPool");
|
||||||
createChannelMethod = Handshake.class.getMethod("createChannel",
|
createChannelMethod = ReflectionUtils.findMethod(Handshake.class, "createChannel", (Class<?>[]) null);
|
||||||
WebSocketHttpExchange.class, StreamConnection.class, getBufferPoolMethod.getReturnType());
|
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException("Incompatible Undertow API version", ex);
|
throw new IllegalStateException("Incompatible Undertow API version", ex);
|
||||||
|
|
@ -162,31 +161,39 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat
|
||||||
|
|
||||||
HttpServletRequest servletRequest = getHttpServletRequest(request);
|
HttpServletRequest servletRequest = getHttpServletRequest(request);
|
||||||
HttpServletResponse servletResponse = getHttpServletResponse(response);
|
HttpServletResponse servletResponse = getHttpServletResponse(response);
|
||||||
|
|
||||||
final ServletWebSocketHttpExchange exchange = createHttpExchange(servletRequest, servletResponse);
|
final ServletWebSocketHttpExchange exchange = createHttpExchange(servletRequest, servletResponse);
|
||||||
exchange.putAttachment(HandshakeUtil.PATH_PARAMS, Collections.<String, String>emptyMap());
|
exchange.putAttachment(HandshakeUtil.PATH_PARAMS, Collections.<String, String>emptyMap());
|
||||||
|
|
||||||
ServerWebSocketContainer wsContainer = (ServerWebSocketContainer) getContainer(servletRequest);
|
ServerWebSocketContainer wsContainer = (ServerWebSocketContainer) getContainer(servletRequest);
|
||||||
final EndpointSessionHandler endpointSessionHandler = new EndpointSessionHandler(wsContainer);
|
final EndpointSessionHandler endpointSessionHandler = new EndpointSessionHandler(wsContainer);
|
||||||
|
|
||||||
final ConfiguredServerEndpoint configuredServerEndpoint = createConfiguredServerEndpoint(
|
final ConfiguredServerEndpoint configuredServerEndpoint = createConfiguredServerEndpoint(
|
||||||
selectedProtocol, selectedExtensions, endpoint, servletRequest);
|
selectedProtocol, selectedExtensions, endpoint, servletRequest);
|
||||||
|
|
||||||
final Handshake handshake = getHandshakeToUse(exchange, configuredServerEndpoint);
|
final Handshake handshake = getHandshakeToUse(exchange, configuredServerEndpoint);
|
||||||
|
|
||||||
exchange.upgradeChannel(new HttpUpgradeListener() {
|
HttpUpgradeListener upgradeListener = (HttpUpgradeListener) Proxy.newProxyInstance(
|
||||||
@Override
|
getClass().getClassLoader(), new Class<?>[] {HttpUpgradeListener.class},
|
||||||
public void handleUpgrade(StreamConnection connection, HttpServerExchange serverExchange) {
|
new InvocationHandler() {
|
||||||
Object bufferPool = ReflectionUtils.invokeMethod(getBufferPoolMethod, exchange);
|
@Override
|
||||||
WebSocketChannel channel = (WebSocketChannel) ReflectionUtils.invokeMethod(
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
createChannelMethod, handshake, exchange, connection, bufferPool);
|
if ("handleUpgrade".equals(method.getName())) {
|
||||||
if (peerConnections != null) {
|
Object connection = args[0]; // currently an XNIO StreamConnection
|
||||||
peerConnections.add(channel);
|
Object bufferPool = ReflectionUtils.invokeMethod(getBufferPoolMethod, exchange);
|
||||||
}
|
WebSocketChannel channel = (WebSocketChannel) ReflectionUtils.invokeMethod(
|
||||||
endpointSessionHandler.onConnect(exchange, channel);
|
createChannelMethod, handshake, exchange, connection, bufferPool);
|
||||||
}
|
if (peerConnections != null) {
|
||||||
});
|
peerConnections.add(channel);
|
||||||
|
}
|
||||||
|
endpointSessionHandler.onConnect(exchange, channel);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// any java.lang.Object method: equals, hashCode, toString...
|
||||||
|
return ReflectionUtils.invokeMethod(method, this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exchange.upgradeChannel(upgradeListener);
|
||||||
handshake.handshake(exchange);
|
handshake.handshake(exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue