17
17
package org .springframework .web .socket .adapter .jetty ;
18
18
19
19
import java .io .IOException ;
20
+ import java .lang .reflect .Method ;
20
21
import java .net .InetSocketAddress ;
21
22
import java .net .URI ;
22
23
import java .security .Principal ;
26
27
27
28
import org .eclipse .jetty .websocket .api .RemoteEndpoint ;
28
29
import org .eclipse .jetty .websocket .api .Session ;
30
+ import org .eclipse .jetty .websocket .api .UpgradeRequest ;
31
+ import org .eclipse .jetty .websocket .api .UpgradeResponse ;
29
32
import org .eclipse .jetty .websocket .api .WebSocketException ;
30
33
import org .eclipse .jetty .websocket .api .extensions .ExtensionConfig ;
31
34
32
35
import org .springframework .http .HttpHeaders ;
33
36
import org .springframework .util .ObjectUtils ;
37
+ import org .springframework .util .ReflectionUtils ;
34
38
import org .springframework .web .socket .BinaryMessage ;
35
39
import org .springframework .web .socket .CloseStatus ;
36
40
import org .springframework .web .socket .PingMessage ;
45
49
*
46
50
* @author Phillip Webb
47
51
* @author Rossen Stoyanchev
52
+ * @author Brian Clozel
48
53
* @since 4.0
49
54
*/
50
55
public class JettyWebSocketSession extends AbstractWebSocketSession <Session > {
51
56
57
+ // As of Jetty 9.4, UpgradeRequest and UpgradeResponse are interfaces instead of classes
58
+ private static final boolean isJetty94 ;
59
+
60
+ private static Method getUpgradeRequest ;
61
+ private static Method getUpgradeResponse ;
62
+ private static Method getRequestURI ;
63
+ private static Method getHeaders ;
64
+ private static Method getAcceptedSubProtocol ;
65
+ private static Method getExtensions ;
66
+ private static Method getUserPrincipal ;
67
+
52
68
private String id ;
53
69
54
70
private URI uri ;
@@ -61,6 +77,23 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
61
77
62
78
private Principal user ;
63
79
80
+ static {
81
+ isJetty94 = UpgradeRequest .class .isInterface ();
82
+ if (!isJetty94 ) {
83
+ try {
84
+ getUpgradeRequest = Session .class .getMethod ("getUpgradeRequest" );
85
+ getUpgradeResponse = Session .class .getMethod ("getUpgradeResponse" );
86
+ getRequestURI = UpgradeRequest .class .getMethod ("getRequestURI" );
87
+ getHeaders = UpgradeRequest .class .getMethod ("getHeaders" );
88
+ getAcceptedSubProtocol = UpgradeResponse .class .getMethod ("getAcceptedSubProtocol" );
89
+ getExtensions = UpgradeResponse .class .getMethod ("getExtensions" );
90
+ getUserPrincipal = UpgradeRequest .class .getMethod ("getUserPrincipal" );
91
+ }
92
+ catch (NoSuchMethodException ex ) {
93
+ throw new IllegalStateException ("Incompatible Jetty API" , ex );
94
+ }
95
+ }
96
+ }
64
97
65
98
/**
66
99
* Create a new {@link JettyWebSocketSession} instance.
@@ -164,20 +197,64 @@ public boolean isOpen() {
164
197
@ Override
165
198
public void initializeNativeSession (Session session ) {
166
199
super .initializeNativeSession (session );
200
+ if (isJetty94 ) {
201
+ initializeJetty94Session (session );
202
+ }
203
+ else {
204
+ initializeJettySession (session );
205
+ }
206
+ }
207
+
208
+ @ SuppressWarnings ("unchecked" )
209
+ private void initializeJettySession (Session session ) {
210
+
211
+ Object request = ReflectionUtils .invokeMethod (getUpgradeRequest , session );
212
+ Object response = ReflectionUtils .invokeMethod (getUpgradeResponse , session );
167
213
214
+ this .id = ObjectUtils .getIdentityHexString (getNativeSession ());
215
+ this .uri = (URI ) ReflectionUtils .invokeMethod (getRequestURI , request );
216
+
217
+ this .headers = new HttpHeaders ();
218
+ this .headers .putAll ((Map <String , List <String >>) ReflectionUtils .invokeMethod (getHeaders , request ));
219
+ this .headers = HttpHeaders .readOnlyHttpHeaders (headers );
220
+
221
+ this .acceptedProtocol = (String ) ReflectionUtils .invokeMethod (getAcceptedSubProtocol , response );
222
+
223
+ List <ExtensionConfig > source = (List <ExtensionConfig >) ReflectionUtils .invokeMethod (getExtensions , response );
224
+ if (source != null ) {
225
+ this .extensions = new ArrayList <WebSocketExtension >(source .size ());
226
+ for (ExtensionConfig ec : source ) {
227
+ this .extensions .add (new WebSocketExtension (ec .getName (), ec .getParameters ()));
228
+ }
229
+ }
230
+ else {
231
+ this .extensions = new ArrayList <WebSocketExtension >(0 );
232
+ }
233
+
234
+ if (this .user == null ) {
235
+ this .user = (Principal ) ReflectionUtils .invokeMethod (getUserPrincipal , request );
236
+ }
237
+ }
238
+
239
+ private void initializeJetty94Session (Session session ) {
168
240
this .id = ObjectUtils .getIdentityHexString (getNativeSession ());
169
241
this .uri = session .getUpgradeRequest ().getRequestURI ();
170
242
171
243
this .headers = new HttpHeaders ();
172
- this .headers .putAll (getNativeSession () .getUpgradeRequest ().getHeaders ());
244
+ this .headers .putAll (session .getUpgradeRequest ().getHeaders ());
173
245
this .headers = HttpHeaders .readOnlyHttpHeaders (headers );
174
246
175
247
this .acceptedProtocol = session .getUpgradeResponse ().getAcceptedSubProtocol ();
176
248
177
249
List <ExtensionConfig > source = getNativeSession ().getUpgradeResponse ().getExtensions ();
178
- this .extensions = new ArrayList <WebSocketExtension >(source .size ());
179
- for (ExtensionConfig ec : source ) {
180
- this .extensions .add (new WebSocketExtension (ec .getName (), ec .getParameters ()));
250
+ if (source != null ) {
251
+ this .extensions = new ArrayList <WebSocketExtension >(source .size ());
252
+ for (ExtensionConfig ec : source ) {
253
+ this .extensions .add (new WebSocketExtension (ec .getName (), ec .getParameters ()));
254
+ }
255
+ }
256
+ else {
257
+ this .extensions = new ArrayList <WebSocketExtension >(0 );
181
258
}
182
259
183
260
if (this .user == null ) {
0 commit comments