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