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.List;
24
25 import javax.websocket.Extension;
26 import javax.websocket.Extension.Parameter;
27 import javax.websocket.server.ServerEndpointConfig;
28 import javax.websocket.server.ServerEndpointConfig.Configurator;
29
30 import org.eclipse.jetty.util.StringUtil;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.log.Logger;
33 import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
34 import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
35 import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
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 private static final Logger LOG = Log.getLogger(JsrCreator.class);
49 private final WebSocketContainerScope containerScope;
50 private final ServerEndpointMetadata metadata;
51 private final ExtensionFactory extensionFactory;
52
53 public JsrCreator(WebSocketContainerScope containerScope, ServerEndpointMetadata metadata, ExtensionFactory extensionFactory)
54 {
55 this.containerScope = containerScope;
56 this.metadata = metadata;
57 this.extensionFactory = extensionFactory;
58 }
59
60 @Override
61 public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
62 {
63 JsrHandshakeRequest hsreq = new JsrHandshakeRequest(req);
64 JsrHandshakeResponse hsresp = new JsrHandshakeResponse(resp);
65
66
67 ServerEndpointConfig config = metadata.getConfig();
68
69
70
71 config = new BasicServerEndpointConfig(containerScope, config);
72
73
74
75
76
77 config.getUserProperties().put(PROP_LOCAL_ADDRESS,req.getLocalSocketAddress());
78 config.getUserProperties().put(PROP_REMOTE_ADDRESS,req.getRemoteSocketAddress());
79
80
81 ServerEndpointConfig.Configurator configurator = config.getConfigurator();
82
83
84 configurator.modifyHandshake(config,hsreq,hsresp);
85
86
87 if (!configurator.checkOrigin(req.getOrigin()))
88 {
89 try
90 {
91 resp.sendForbidden("Origin mismatch");
92 }
93 catch (IOException e)
94 {
95 if (LOG.isDebugEnabled())
96 LOG.debug("Unable to send error response",e);
97 }
98 return null;
99 }
100
101
102 List<String> supported = config.getSubprotocols();
103 List<String> requested = req.getSubProtocols();
104 String subprotocol = configurator.getNegotiatedSubprotocol(supported,requested);
105 if (StringUtil.isNotBlank(subprotocol))
106 {
107 resp.setAcceptedSubProtocol(subprotocol);
108 }
109
110
111 List<Extension> installedExts = new ArrayList<>();
112 for (String extName : extensionFactory.getAvailableExtensions().keySet())
113 {
114 installedExts.add(new JsrExtension(extName));
115 }
116 List<Extension> requestedExts = new ArrayList<>();
117 for (ExtensionConfig reqCfg : req.getExtensions())
118 {
119 requestedExts.add(new JsrExtension(reqCfg));
120 }
121 List<Extension> usedExts = configurator.getNegotiatedExtensions(installedExts,requestedExts);
122 List<ExtensionConfig> configs = new ArrayList<>();
123 if (usedExts != null)
124 {
125 for (Extension used : usedExts)
126 {
127 ExtensionConfig ecfg = new ExtensionConfig(used.getName());
128 for (Parameter param : used.getParameters())
129 {
130 ecfg.setParameter(param.getName(),param.getValue());
131 }
132 configs.add(ecfg);
133 }
134 }
135 resp.setExtensions(configs);
136
137
138 try
139 {
140 Class<?> endpointClass = config.getEndpointClass();
141 Configurator configr = config.getConfigurator();
142 Object endpoint = configr.getEndpointInstance(endpointClass);
143
144
145 PathSpec pathSpec = hsreq.getRequestPathSpec();
146 if (pathSpec instanceof WebSocketPathSpec)
147 {
148
149 WebSocketPathSpec wspathSpec = (WebSocketPathSpec)pathSpec;
150 String requestPath = req.getRequestPath();
151
152 config = new PathParamServerEndpointConfig(containerScope,config,wspathSpec,requestPath);
153 }
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 }