17
17
package org .springframework .web .socket .server .jetty ;
18
18
19
19
import java .io .IOException ;
20
+ import java .lang .reflect .Method ;
20
21
import java .security .Principal ;
21
22
import java .util .ArrayList ;
22
23
import java .util .List ;
26
27
import javax .servlet .http .HttpServletRequest ;
27
28
import javax .servlet .http .HttpServletResponse ;
28
29
29
- import org .eclipse .jetty .util .DecoratedObjectFactory ;
30
+ import org .eclipse .jetty .websocket .api .UpgradeRequest ;
31
+ import org .eclipse .jetty .websocket .api .UpgradeResponse ;
30
32
import org .eclipse .jetty .websocket .api .WebSocketPolicy ;
31
33
import org .eclipse .jetty .websocket .api .extensions .ExtensionConfig ;
32
34
import org .eclipse .jetty .websocket .server .HandshakeRFC6455 ;
54
56
import org .springframework .web .socket .server .RequestUpgradeStrategy ;
55
57
56
58
/**
57
- * A {@link RequestUpgradeStrategy} for use with Jetty 9.1 -9.3. Based on Jetty's
59
+ * A {@link RequestUpgradeStrategy} for use with Jetty 9.0 -9.3. Based on Jetty's
58
60
* internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class.
59
61
*
60
62
* @author Phillip Webb
61
63
* @author Rossen Stoyanchev
62
- * @author Brian Clozel
63
64
* @since 4.0
64
65
*/
65
66
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy , Lifecycle , ServletContextAware {
66
67
68
+ // Pre-Jetty 9.3 init method without ServletContext
69
+ private static final Method webSocketFactoryInitMethod =
70
+ ClassUtils .getMethodIfAvailable (WebSocketServerFactory .class , "init" );
71
+
67
72
private static final ThreadLocal <WebSocketHandlerContainer > wsContainerHolder =
68
73
new NamedThreadLocal <WebSocketHandlerContainer >("WebSocket Handler Container" );
69
74
70
- // Actually 9.3.15+
71
- private static boolean isJetty94 = ClassUtils .hasConstructor (WebSocketServerFactory .class , ServletContext .class );
72
-
73
- private static boolean isJetty91 = ClassUtils .hasMethod (WebSocketServerFactory .class , "init" );
74
75
75
- private WebSocketServerFactoryAdapter factoryAdapter ;
76
+ private final WebSocketServerFactory factory ;
76
77
77
78
private volatile List <WebSocketExtension > supportedExtensions ;
78
79
79
- protected ServletContext servletContext ;
80
+ private ServletContext servletContext ;
80
81
81
82
private volatile boolean running = false ;
82
83
84
+
83
85
/**
84
86
* Default constructor that creates {@link WebSocketServerFactory} through
85
87
* its default constructor thus using a default {@link WebSocketPolicy}.
86
88
*/
87
89
public JettyRequestUpgradeStrategy () {
88
- this (WebSocketPolicy . newServerPolicy ());
90
+ this (new WebSocketServerFactory ());
89
91
}
90
92
91
93
/**
92
- * A constructor accepting a {@link WebSocketPolicy}
93
- * to be used when creating the {@link WebSocketServerFactory} instance.
94
- * @since 4.3
94
+ * A constructor accepting a {@link WebSocketServerFactory}.
95
+ * This may be useful for modifying the factory's {@link WebSocketPolicy}
96
+ * via {@link WebSocketServerFactory#getPolicy()}.
95
97
*/
96
- public JettyRequestUpgradeStrategy (WebSocketPolicy webSocketPolicy ) {
97
- this .factoryAdapter = isJetty94 ? new Jetty94WebSocketServerFactoryAdapter ()
98
- : new JettyWebSocketServerFactoryAdapter ();
99
- this .factoryAdapter .setWebSocketPolicy (webSocketPolicy );
98
+ public JettyRequestUpgradeStrategy (WebSocketServerFactory factory ) {
99
+ Assert .notNull (factory , "WebSocketServerFactory must not be null" );
100
+ this .factory = factory ;
101
+ this .factory .setCreator (new WebSocketCreator () {
102
+ @ Override
103
+ public Object createWebSocket (ServletUpgradeRequest request , ServletUpgradeResponse response ) {
104
+ // Cast to avoid infinite recursion
105
+ return createWebSocket ((UpgradeRequest ) request , (UpgradeResponse ) response );
106
+ }
107
+ // For Jetty 9.0.x
108
+ public Object createWebSocket (UpgradeRequest request , UpgradeResponse response ) {
109
+ WebSocketHandlerContainer container = wsContainerHolder .get ();
110
+ Assert .state (container != null , "Expected WebSocketHandlerContainer" );
111
+ response .setAcceptedSubProtocol (container .getSelectedProtocol ());
112
+ response .setExtensions (container .getExtensionConfigs ());
113
+ return container .getHandler ();
114
+ }
115
+ });
100
116
}
101
117
118
+
102
119
@ Override
103
120
public String [] getSupportedVersions () {
104
- return new String [] {String .valueOf (HandshakeRFC6455 .VERSION )};
121
+ return new String [] { String .valueOf (HandshakeRFC6455 .VERSION ) };
105
122
}
106
123
107
124
@ Override
@@ -114,7 +131,7 @@ public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request
114
131
115
132
private List <WebSocketExtension > getWebSocketExtensions () {
116
133
List <WebSocketExtension > result = new ArrayList <WebSocketExtension >();
117
- for (String name : this .factoryAdapter . getFactory () .getExtensionFactory ().getExtensionNames ()) {
134
+ for (String name : this .factory .getExtensionFactory ().getExtensionNames ()) {
118
135
result .add (new WebSocketExtension (name ));
119
136
}
120
137
return result ;
@@ -136,24 +153,24 @@ public void start() {
136
153
if (!isRunning ()) {
137
154
this .running = true ;
138
155
try {
139
- this .factoryAdapter .start ();
156
+ if (webSocketFactoryInitMethod != null ) {
157
+ webSocketFactoryInitMethod .invoke (this .factory );
158
+ }
159
+ else {
160
+ this .factory .init (this .servletContext );
161
+ }
140
162
}
141
163
catch (Exception ex ) {
142
- throw new IllegalStateException ("Unable to start Jetty WebSocketServerFactory" , ex );
164
+ throw new IllegalStateException ("Unable to initialize Jetty WebSocketServerFactory" , ex );
143
165
}
144
166
}
145
167
}
146
168
147
169
@ Override
148
170
public void stop () {
149
171
if (isRunning ()) {
150
- try {
151
- this .running = false ;
152
- factoryAdapter .stop ();
153
- }
154
- catch (Exception ex ) {
155
- throw new IllegalStateException ("Unable to stop Jetty WebSocketServerFactory" , ex );
156
- }
172
+ this .running = false ;
173
+ this .factory .cleanup ();
157
174
}
158
175
}
159
176
@@ -168,8 +185,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
168
185
Assert .isInstanceOf (ServletServerHttpResponse .class , response );
169
186
HttpServletResponse servletResponse = ((ServletServerHttpResponse ) response ).getServletResponse ();
170
187
171
- Assert .isTrue (this .factoryAdapter .getFactory ()
172
- .isUpgradeRequest (servletRequest , servletResponse ), "Not a WebSocket handshake" );
188
+ Assert .isTrue (this .factory .isUpgradeRequest (servletRequest , servletResponse ), "Not a WebSocket handshake" );
173
189
174
190
JettyWebSocketSession session = new JettyWebSocketSession (attributes , user );
175
191
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter (wsHandler , session );
@@ -179,7 +195,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
179
195
180
196
try {
181
197
wsContainerHolder .set (container );
182
- this .factoryAdapter . getFactory () .acceptWebSocket (servletRequest , servletResponse );
198
+ this .factory .acceptWebSocket (servletRequest , servletResponse );
183
199
}
184
200
catch (IOException ex ) {
185
201
throw new HandshakeFailureException (
@@ -203,7 +219,7 @@ public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter handler, String pr
203
219
this .handler = handler ;
204
220
this .selectedProtocol = protocol ;
205
221
if (CollectionUtils .isEmpty (extensions )) {
206
- this .extensionConfigs = new ArrayList < ExtensionConfig >() ;
222
+ this .extensionConfigs = null ;
207
223
}
208
224
else {
209
225
this .extensionConfigs = new ArrayList <ExtensionConfig >();
@@ -226,74 +242,4 @@ public List<ExtensionConfig> getExtensionConfigs() {
226
242
}
227
243
}
228
244
229
- private static abstract class WebSocketServerFactoryAdapter {
230
-
231
- protected WebSocketServerFactory factory ;
232
-
233
- protected WebSocketPolicy webSocketPolicy ;
234
-
235
- public WebSocketServerFactory getFactory () {
236
- return factory ;
237
- }
238
-
239
- public void setWebSocketPolicy (WebSocketPolicy webSocketPolicy ) {
240
- this .webSocketPolicy = webSocketPolicy ;
241
- }
242
-
243
- protected void configureFactory () {
244
- this .factory .setCreator (new WebSocketCreator () {
245
- @ Override
246
- public Object createWebSocket (ServletUpgradeRequest request , ServletUpgradeResponse response ) {
247
- WebSocketHandlerContainer container = wsContainerHolder .get ();
248
- Assert .state (container != null , "Expected WebSocketHandlerContainer" );
249
- response .setAcceptedSubProtocol (container .getSelectedProtocol ());
250
- response .setExtensions (container .getExtensionConfigs ());
251
- return container .getHandler ();
252
- }
253
- });
254
- }
255
-
256
- abstract void start () throws Exception ;
257
-
258
- abstract void stop () throws Exception ;
259
- }
260
-
261
- private class JettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
262
-
263
- @ Override
264
- void start () throws Exception {
265
- this .factory = WebSocketServerFactory .class .getConstructor (WebSocketPolicy .class )
266
- .newInstance (this .webSocketPolicy );
267
- configureFactory ();
268
- if (isJetty91 ) {
269
- WebSocketServerFactory .class .getMethod ("init" ).invoke (this .factory );
270
- }
271
- else {
272
- WebSocketServerFactory .class .getMethod ("init" , ServletContext .class )
273
- .invoke (this .factory , servletContext );
274
- }
275
- }
276
-
277
- @ Override
278
- void stop () throws Exception {
279
- WebSocketServerFactory .class .getMethod ("cleanup" ).invoke (this .factory );
280
- }
281
- }
282
-
283
- private class Jetty94WebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
284
-
285
- @ Override
286
- void start () throws Exception {
287
- servletContext .setAttribute (DecoratedObjectFactory .ATTR , new DecoratedObjectFactory ());
288
- this .factory = new WebSocketServerFactory (servletContext , this .webSocketPolicy );
289
- configureFactory ();
290
- this .factory .start ();
291
- }
292
-
293
- @ Override
294
- void stop () throws Exception {
295
- this .factory .stop ();
296
- }
297
- }
298
-
299
245
}
0 commit comments