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 ;
@@ -72,7 +73,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
72
73
private WebSocketPolicy policy ;
73
74
74
75
@ Nullable
75
- private WebSocketServerFactory factory ;
76
+ private volatile WebSocketServerFactory factory ;
76
77
77
78
@ Nullable
78
79
private ServletContext servletContext ;
@@ -122,17 +123,20 @@ public void start() {
122
123
if (!isRunning ()) {
123
124
this .running = true ;
124
125
try {
125
- if (this .factory == null ) {
126
- 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 ;
127
131
}
128
- this . factory .setCreator ((request , response ) -> {
132
+ factory .setCreator ((request , response ) -> {
129
133
WebSocketHandlerContainer container = containerHolder .get ();
130
134
Assert .state (container != null , "Expected WebSocketHandlerContainer" );
131
135
response .setAcceptedSubProtocol (container .getSelectedProtocol ());
132
136
response .setExtensions (container .getExtensionConfigs ());
133
137
return container .getHandler ();
134
138
});
135
- this . factory .start ();
139
+ factory .start ();
136
140
}
137
141
catch (Throwable ex ) {
138
142
throw new IllegalStateException ("Unable to start Jetty WebSocketServerFactory" , ex );
@@ -144,9 +148,10 @@ public void start() {
144
148
public void stop () {
145
149
if (isRunning ()) {
146
150
this .running = false ;
147
- if (this .factory != null ) {
151
+ WebSocketServerFactory factory = this .factory ;
152
+ if (factory != null ) {
148
153
try {
149
- this . factory .stop ();
154
+ factory .stop ();
150
155
}
151
156
catch (Throwable ex ) {
152
157
throw new IllegalStateException ("Unable to stop Jetty WebSocketServerFactory" , ex );
@@ -168,10 +173,12 @@ public String[] getSupportedVersions() {
168
173
169
174
@ Override
170
175
public List <WebSocketExtension > getSupportedExtensions (ServerHttpRequest request ) {
171
- if (this .supportedExtensions == null ) {
172
- this .supportedExtensions = buildWebSocketExtensions ();
176
+ List <WebSocketExtension > extensions = this .supportedExtensions ;
177
+ if (extensions == null ) {
178
+ extensions = buildWebSocketExtensions ();
179
+ this .supportedExtensions = extensions ;
173
180
}
174
- return this . supportedExtensions ;
181
+ return extensions ;
175
182
}
176
183
177
184
private List <WebSocketExtension > buildWebSocketExtensions () {
@@ -185,16 +192,19 @@ private List<WebSocketExtension> buildWebSocketExtensions() {
185
192
186
193
@ SuppressWarnings ({"unchecked" , "deprecation" })
187
194
private Set <String > getExtensionNames () {
195
+ WebSocketServerFactory factory = this .factory ;
196
+ Assert .state (factory != null , "No WebSocketServerFactory available" );
188
197
try {
189
- return this . factory .getAvailableExtensionNames ();
198
+ return factory .getAvailableExtensionNames ();
190
199
}
191
200
catch (IncompatibleClassChangeError ex ) {
192
201
// Fallback for versions prior to 9.4.21:
193
202
// 9.4.20.v20190813: ExtensionFactory (abstract class -> interface)
194
203
// 9.4.21.v20190926: ExtensionFactory (interface -> abstract class) + deprecated
195
204
Class <?> clazz = org .eclipse .jetty .websocket .api .extensions .ExtensionFactory .class ;
196
205
Method method = ClassUtils .getMethod (clazz , "getExtensionNames" );
197
- 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 ());
198
208
}
199
209
}
200
210
@@ -209,7 +219,9 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
209
219
Assert .isInstanceOf (ServletServerHttpResponse .class , response , "ServletServerHttpResponse required" );
210
220
HttpServletResponse servletResponse = ((ServletServerHttpResponse ) response ).getServletResponse ();
211
221
212
- 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" );
213
225
214
226
JettyWebSocketSession session = new JettyWebSocketSession (attributes , user );
215
227
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter (wsHandler , session );
@@ -219,7 +231,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
219
231
220
232
try {
221
233
containerHolder .set (container );
222
- this . factory .acceptWebSocket (servletRequest , servletResponse );
234
+ factory .acceptWebSocket (servletRequest , servletResponse );
223
235
}
224
236
catch (IOException ex ) {
225
237
throw new HandshakeFailureException (
@@ -235,12 +247,13 @@ private static class WebSocketHandlerContainer {
235
247
236
248
private final JettyWebSocketHandlerAdapter handler ;
237
249
250
+ @ Nullable
238
251
private final String selectedProtocol ;
239
252
240
253
private final List <ExtensionConfig > extensionConfigs ;
241
254
242
- public WebSocketHandlerContainer (
243
- JettyWebSocketHandlerAdapter handler , String protocol , List <WebSocketExtension > extensions ) {
255
+ public WebSocketHandlerContainer (JettyWebSocketHandlerAdapter handler ,
256
+ @ Nullable String protocol , List <WebSocketExtension > extensions ) {
244
257
245
258
this .handler = handler ;
246
259
this .selectedProtocol = protocol ;
@@ -259,6 +272,7 @@ public JettyWebSocketHandlerAdapter getHandler() {
259
272
return this .handler ;
260
273
}
261
274
275
+ @ Nullable
262
276
public String getSelectedProtocol () {
263
277
return this .selectedProtocol ;
264
278
}
0 commit comments