1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.jsr356.server;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.websocket.Extension;
28 import javax.websocket.Extension.Parameter;
29 import javax.websocket.server.ServerEndpointConfig;
30
31 import org.eclipse.jetty.util.StringUtil;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34 import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
35 import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
36 import org.eclipse.jetty.websocket.jsr356.JsrExtension;
37 import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
38 import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec;
39 import org.eclipse.jetty.websocket.server.pathmap.PathSpec;
40 import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
41 import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
42 import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
43
44 public class JsrCreator implements WebSocketCreator
45 {
46 public static final String PROP_REMOTE_ADDRESS = "javax.websocket.endpoint.remoteAddress";
47 public static final String PROP_LOCAL_ADDRESS = "javax.websocket.endpoint.localAddress";
48 public static final String PROP_LOCALES = "javax.websocket.upgrade.locales";
49 private static final Logger LOG = Log.getLogger(JsrCreator.class);
50 private final ServerEndpointMetadata metadata;
51 private final ExtensionFactory extensionFactory;
52
53 public JsrCreator(ServerEndpointMetadata metadata, ExtensionFactory extensionFactory)
54 {
55 this.metadata = metadata;
56 this.extensionFactory = extensionFactory;
57 }
58
59 @Override
60 public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
61 {
62 JsrHandshakeRequest jsrHandshakeRequest = new JsrHandshakeRequest(req);
63 JsrHandshakeResponse jsrHandshakeResponse = new JsrHandshakeResponse(resp);
64
65
66 ServerEndpointConfig config = metadata.getConfig();
67
68
69
70 config = new BasicServerEndpointConfig(config);
71
72
73
74
75
76 Map<String, Object> userProperties = config.getUserProperties();
77 userProperties.put(PROP_LOCAL_ADDRESS,req.getLocalSocketAddress());
78 userProperties.put(PROP_REMOTE_ADDRESS,req.getRemoteSocketAddress());
79 userProperties.put(PROP_LOCALES,Collections.list(req.getLocales()));
80
81
82 ServerEndpointConfig.Configurator configurator = config.getConfigurator();
83
84
85 if (!configurator.checkOrigin(req.getOrigin()))
86 {
87 try
88 {
89 resp.sendForbidden("Origin mismatch");
90 }
91 catch (IOException e)
92 {
93 if (LOG.isDebugEnabled())
94 LOG.debug("Unable to send error response",e);
95 }
96 return null;
97 }
98
99
100 List<String> supported = config.getSubprotocols();
101 List<String> requested = req.getSubProtocols();
102 String subprotocol = configurator.getNegotiatedSubprotocol(supported,requested);
103 if (StringUtil.isNotBlank(subprotocol))
104 {
105 resp.setAcceptedSubProtocol(subprotocol);
106 }
107
108
109 List<Extension> installedExtensions = new ArrayList<>();
110 for (String extName : extensionFactory.getAvailableExtensions().keySet())
111 {
112 installedExtensions.add(new JsrExtension(extName));
113 }
114 List<Extension> requestedExts = new ArrayList<>();
115 for (ExtensionConfig reqCfg : req.getExtensions())
116 {
117 requestedExts.add(new JsrExtension(reqCfg));
118 }
119 List<Extension> usedExtensions = configurator.getNegotiatedExtensions(installedExtensions,requestedExts);
120 List<ExtensionConfig> configs = new ArrayList<>();
121 if (usedExtensions != null)
122 {
123 for (Extension used : usedExtensions)
124 {
125 ExtensionConfig ecfg = new ExtensionConfig(used.getName());
126 for (Parameter param : used.getParameters())
127 {
128 ecfg.setParameter(param.getName(),param.getValue());
129 }
130 configs.add(ecfg);
131 }
132 }
133 resp.setExtensions(configs);
134
135
136 PathSpec pathSpec = jsrHandshakeRequest.getRequestPathSpec();
137 if (pathSpec instanceof WebSocketPathSpec)
138 {
139
140 WebSocketPathSpec wspathSpec = (WebSocketPathSpec)pathSpec;
141 String requestPath = req.getRequestPath();
142
143 config = new PathParamServerEndpointConfig(config,wspathSpec,requestPath);
144 }
145
146
147 configurator.modifyHandshake(config,jsrHandshakeRequest,jsrHandshakeResponse);
148
149 try
150 {
151
152 Class<?> endpointClass = config.getEndpointClass();
153 Object endpoint = config.getConfigurator().getEndpointInstance(endpointClass);
154 return new EndpointInstance(endpoint,config,metadata);
155 }
156 catch (InstantiationException e)
157 {
158 if (LOG.isDebugEnabled())
159 LOG.debug("Unable to create websocket: " + config.getEndpointClass().getName(),e);
160 return null;
161 }
162 }
163
164 @Override
165 public String toString()
166 {
167 return String.format("%s[metadata=%s]",this.getClass().getName(),metadata);
168 }
169 }