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