|
17 | 17 | package org.springframework.web.socket.server.standard;
|
18 | 18 |
|
19 | 19 | import java.lang.reflect.Constructor;
|
| 20 | +import java.lang.reflect.InvocationHandler; |
20 | 21 | import java.lang.reflect.Method;
|
| 22 | +import java.lang.reflect.Proxy; |
21 | 23 | import java.util.Arrays;
|
22 | 24 | import java.util.Collections;
|
23 | 25 | import java.util.List;
|
|
31 | 33 | import javax.websocket.Extension;
|
32 | 34 | import javax.websocket.server.ServerEndpointConfig;
|
33 | 35 |
|
34 |
| -import io.undertow.server.HttpServerExchange; |
35 | 36 | import io.undertow.server.HttpUpgradeListener;
|
36 | 37 | import io.undertow.servlet.api.InstanceFactory;
|
37 | 38 | import io.undertow.servlet.api.InstanceHandle;
|
|
50 | 51 | import io.undertow.websockets.jsr.handshake.JsrHybi08Handshake;
|
51 | 52 | import io.undertow.websockets.jsr.handshake.JsrHybi13Handshake;
|
52 | 53 | import io.undertow.websockets.spi.WebSocketHttpExchange;
|
53 |
| -import org.xnio.StreamConnection; |
54 | 54 |
|
55 | 55 | import org.springframework.http.server.ServerHttpRequest;
|
56 | 56 | import org.springframework.http.server.ServerHttpResponse;
|
@@ -122,8 +122,7 @@ public class UndertowRequestUpgradeStrategy extends AbstractStandardUpgradeStrat
|
122 | 122 |
|
123 | 123 | // Adapting between different Pool API types in Undertow 1.0-1.2 vs 1.3
|
124 | 124 | 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); |
127 | 126 | }
|
128 | 127 | catch (Throwable ex) {
|
129 | 128 | throw new IllegalStateException("Incompatible Undertow API version", ex);
|
@@ -162,31 +161,39 @@ protected void upgradeInternal(ServerHttpRequest request, ServerHttpResponse res
|
162 | 161 |
|
163 | 162 | HttpServletRequest servletRequest = getHttpServletRequest(request);
|
164 | 163 | HttpServletResponse servletResponse = getHttpServletResponse(response);
|
165 |
| - |
166 | 164 | final ServletWebSocketHttpExchange exchange = createHttpExchange(servletRequest, servletResponse);
|
167 | 165 | exchange.putAttachment(HandshakeUtil.PATH_PARAMS, Collections.<String, String>emptyMap());
|
168 | 166 |
|
169 | 167 | ServerWebSocketContainer wsContainer = (ServerWebSocketContainer) getContainer(servletRequest);
|
170 | 168 | final EndpointSessionHandler endpointSessionHandler = new EndpointSessionHandler(wsContainer);
|
171 |
| - |
172 | 169 | final ConfiguredServerEndpoint configuredServerEndpoint = createConfiguredServerEndpoint(
|
173 | 170 | selectedProtocol, selectedExtensions, endpoint, servletRequest);
|
174 |
| - |
175 | 171 | final Handshake handshake = getHandshakeToUse(exchange, configuredServerEndpoint);
|
176 | 172 |
|
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); |
190 | 197 | handshake.handshake(exchange);
|
191 | 198 | }
|
192 | 199 |
|
|
0 commit comments