1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
20
20
import java .lang .reflect .Method ;
21
21
import java .security .Principal ;
22
22
import java .util .ArrayList ;
23
+ import java .util .Collections ;
23
24
import java .util .List ;
24
25
import java .util .Map ;
25
26
import java .util .Set ;
39
40
import org .springframework .http .server .ServerHttpResponse ;
40
41
import org .springframework .http .server .ServletServerHttpRequest ;
41
42
import org .springframework .http .server .ServletServerHttpResponse ;
43
+ import org .springframework .lang .Nullable ;
42
44
import org .springframework .util .Assert ;
43
45
import org .springframework .util .ClassUtils ;
44
46
import org .springframework .util .CollectionUtils ;
@@ -67,15 +69,18 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
67
69
private static final ThreadLocal <WebSocketHandlerContainer > containerHolder =
68
70
new NamedThreadLocal <>("WebSocketHandlerContainer" );
69
71
70
-
72
+ @ Nullable
71
73
private WebSocketPolicy policy ;
72
74
73
- private WebSocketServerFactory factory ;
75
+ @ Nullable
76
+ private volatile WebSocketServerFactory factory ;
74
77
78
+ @ Nullable
75
79
private ServletContext servletContext ;
76
80
77
81
private volatile boolean running = false ;
78
82
83
+ @ Nullable
79
84
private volatile List <WebSocketExtension > supportedExtensions ;
80
85
81
86
@@ -118,17 +123,20 @@ public void start() {
118
123
if (!isRunning ()) {
119
124
this .running = true ;
120
125
try {
121
- if (this .factory == null ) {
122
- this .factory = new WebSocketServerFactory (this .servletContext , this .policy );
126
+ WebSocketServerFactory factory = this .factory ;
127
+ if (factory == null ) {
128
+ Assert .state (this .servletContext != null , "No ServletContext set" );
129
+ factory = new WebSocketServerFactory (this .servletContext , this .policy );
130
+ this .factory = factory ;
123
131
}
124
- this . factory .setCreator ((request , response ) -> {
132
+ factory .setCreator ((request , response ) -> {
125
133
WebSocketHandlerContainer container = containerHolder .get ();
126
134
Assert .state (container != null , "Expected WebSocketHandlerContainer" );
127
135
response .setAcceptedSubProtocol (container .getSelectedProtocol ());
128
136
response .setExtensions (container .getExtensionConfigs ());
129
137
return container .getHandler ();
130
138
});
131
- this . factory .start ();
139
+ factory .start ();
132
140
}
133
141
catch (Throwable ex ) {
134
142
throw new IllegalStateException ("Unable to start Jetty WebSocketServerFactory" , ex );
@@ -140,9 +148,10 @@ public void start() {
140
148
public void stop () {
141
149
if (isRunning ()) {
142
150
this .running = false ;
143
- if (this .factory != null ) {
151
+ WebSocketServerFactory factory = this .factory ;
152
+ if (factory != null ) {
144
153
try {
145
- this . factory .stop ();
154
+ factory .stop ();
146
155
}
147
156
catch (Throwable ex ) {
148
157
throw new IllegalStateException ("Unable to stop Jetty WebSocketServerFactory" , ex );
@@ -164,10 +173,12 @@ public String[] getSupportedVersions() {
164
173
165
174
@ Override
166
175
public List <WebSocketExtension > getSupportedExtensions (ServerHttpRequest request ) {
167
- if (this .supportedExtensions == null ) {
168
- this .supportedExtensions = buildWebSocketExtensions ();
176
+ List <WebSocketExtension > extensions = this .supportedExtensions ;
177
+ if (extensions == null ) {
178
+ extensions = buildWebSocketExtensions ();
179
+ this .supportedExtensions = extensions ;
169
180
}
170
- return this . supportedExtensions ;
181
+ return extensions ;
171
182
}
172
183
173
184
private List <WebSocketExtension > buildWebSocketExtensions () {
@@ -181,22 +192,25 @@ private List<WebSocketExtension> buildWebSocketExtensions() {
181
192
182
193
@ SuppressWarnings ({"unchecked" , "deprecation" })
183
194
private Set <String > getExtensionNames () {
195
+ WebSocketServerFactory factory = this .factory ;
196
+ Assert .state (factory != null , "No WebSocketServerFactory available" );
184
197
try {
185
- return this . factory .getAvailableExtensionNames ();
198
+ return factory .getAvailableExtensionNames ();
186
199
}
187
200
catch (IncompatibleClassChangeError ex ) {
188
201
// Fallback for versions prior to 9.4.21:
189
202
// 9.4.20.v20190813: ExtensionFactory (abstract class -> interface)
190
203
// 9.4.21.v20190926: ExtensionFactory (interface -> abstract class) + deprecated
191
204
Class <?> clazz = org .eclipse .jetty .websocket .api .extensions .ExtensionFactory .class ;
192
205
Method method = ClassUtils .getMethod (clazz , "getExtensionNames" );
193
- return (Set <String >) ReflectionUtils .invokeMethod (method , this .factory .getExtensionFactory ());
206
+ Set <String > result = (Set <String >) ReflectionUtils .invokeMethod (method , factory .getExtensionFactory ());
207
+ return (result != null ? result : Collections .emptySet ());
194
208
}
195
209
}
196
210
197
211
@ Override
198
212
public void upgrade (ServerHttpRequest request , ServerHttpResponse response ,
199
- String selectedProtocol , List <WebSocketExtension > selectedExtensions , Principal user ,
213
+ @ Nullable String selectedProtocol , List <WebSocketExtension > selectedExtensions , @ Nullable Principal user ,
200
214
WebSocketHandler wsHandler , Map <String , Object > attributes ) throws HandshakeFailureException {
201
215
202
216
Assert .isInstanceOf (ServletServerHttpRequest .class , request , "ServletServerHttpRequest required" );
@@ -205,7 +219,9 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
205
219
Assert .isInstanceOf (ServletServerHttpResponse .class , response , "ServletServerHttpResponse required" );
206
220
HttpServletResponse servletResponse = ((ServletServerHttpResponse ) response ).getServletResponse ();
207
221
208
- Assert .isTrue (this .factory .isUpgradeRequest (servletRequest , servletResponse ), "Not a WebSocket handshake" );
222
+ WebSocketServerFactory factory = this .factory ;
223
+ Assert .state (factory != null , "No WebSocketServerFactory available" );
224
+ Assert .isTrue (factory .isUpgradeRequest (servletRequest , servletResponse ), "Not a WebSocket handshake" );
209
225
210
226
JettyWebSocketSession session = new JettyWebSocketSession (attributes , user );
211
227
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter (wsHandler , session );
@@ -215,7 +231,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
215
231
216
232
try {
217
233
containerHolder .set (container );
218
- this . factory .acceptWebSocket (servletRequest , servletResponse );
234
+ factory .acceptWebSocket (servletRequest , servletResponse );
219
235
}
220
236
catch (IOException ex ) {
221
237
throw new HandshakeFailureException (
@@ -231,12 +247,13 @@ private static class WebSocketHandlerContainer {
231
247
232
248
private final JettyWebSocketHandlerAdapter handler ;
233
249
250
+ @ Nullable
234
251
private final String selectedProtocol ;
235
252
236
253
private final List <ExtensionConfig > extensionConfigs ;
237
254
238
- public WebSocketHandlerContainer (
239
- JettyWebSocketHandlerAdapter handler , String protocol , List <WebSocketExtension > extensions ) {
255
+ public WebSocketHandlerContainer (JettyWebSocketHandlerAdapter handler ,
256
+ @ Nullable String protocol , List <WebSocketExtension > extensions ) {
240
257
241
258
this .handler = handler ;
242
259
this .selectedProtocol = protocol ;
@@ -255,6 +272,7 @@ public JettyWebSocketHandlerAdapter getHandler() {
255
272
return this .handler ;
256
273
}
257
274
275
+ @ Nullable
258
276
public String getSelectedProtocol () {
259
277
return this .selectedProtocol ;
260
278
}
0 commit comments