]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.ext.equinox.jetty/src/org/argeo/equinox/jetty/WebSocketJettyCustomizer.java
83934537c364a99e08d6304d35d4244e03d53b08
[lgpl/argeo-commons.git] / org.argeo.ext.equinox.jetty / src / org / argeo / equinox / jetty / WebSocketJettyCustomizer.java
1 package org.argeo.equinox.jetty;
2
3 import java.net.HttpCookie;
4 import java.util.Collection;
5 import java.util.Dictionary;
6 import java.util.List;
7
8 import javax.servlet.ServletException;
9 import javax.servlet.http.HttpSession;
10
11 import org.argeo.cms.auth.CmsSession;
12 import org.eclipse.equinox.http.jetty.JettyCustomizer;
13 import org.eclipse.jetty.servlet.ServletContextHandler;
14 import org.eclipse.jetty.websocket.api.UpgradeRequest;
15 import org.eclipse.jetty.websocket.api.UpgradeResponse;
16 import org.eclipse.jetty.websocket.common.WebSocketSession;
17 import org.eclipse.jetty.websocket.common.WebSocketSessionListener;
18 import org.eclipse.jetty.websocket.jsr356.JsrSession;
19 import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
20 import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
21 import org.osgi.framework.BundleContext;
22 import org.osgi.framework.FrameworkUtil;
23 import org.osgi.framework.InvalidSyntaxException;
24 import org.osgi.framework.ServiceReference;
25 import org.osgi.service.http.HttpContext;
26 import org.osgi.service.useradmin.Authorization;
27
28 public class WebSocketJettyCustomizer extends JettyCustomizer {
29 private BundleContext bc = FrameworkUtil.getBundle(WebSocketJettyCustomizer.class).getBundleContext();
30
31 @Override
32 public Object customizeContext(Object context, Dictionary<String, ?> settings) {
33 ServletContextHandler servletContextHandler = (ServletContextHandler) context;
34 new WebSocketInit(servletContextHandler).start();
35 // servletContextHandler.addFilter(new FilterHolder(new Filter() {
36 //
37 // @Override
38 // public void init(FilterConfig filterConfig) throws ServletException {
39 // // TODO Auto-generated method stub
40 //
41 // }
42 //
43 // @Override
44 // public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
45 // throws IOException, ServletException {
46 // HttpServletRequest httpRequest = (HttpServletRequest) request;
47 // HttpServletResponse httpResponse = (HttpServletResponse) response;
48 //
49 // HttpRequestCallbackHandler callbackHandler = new HttpRequestCallbackHandler(httpRequest, httpResponse);
50 // try {
51 // LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, callbackHandler);
52 // lc.login();
53 //
54 // chain.doFilter(httpRequest, httpResponse);
55 // } catch (LoginException e) {
56 // httpResponse.setStatus(403);
57 // }
58 //
59 // }
60 //
61 // @Override
62 // public void destroy() {
63 // // TODO Auto-generated method stub
64 //
65 // }
66 // }), "/vje/events", EnumSet.of(DispatcherType.REQUEST));
67 return super.customizeContext(context, settings);
68 }
69
70 /** Configure websocket container asynchronously as it may take some time */
71 private class WebSocketInit extends Thread {
72 ServletContextHandler servletContextHandler;
73
74 public WebSocketInit(ServletContextHandler servletContextHandler) {
75 super("WebSocket Init");
76 this.servletContextHandler = servletContextHandler;
77 }
78
79 @Override
80 public void run() {
81 ServerContainer serverContainer;
82 try {
83 serverContainer = WebSocketServerContainerInitializer.configureContext(servletContextHandler);
84 serverContainer.addSessionListener(new WebSocketSessionListener() {
85
86 @Override
87 public void onSessionOpened(WebSocketSession session) {
88 UpgradeRequest upgradeRequest = session.getUpgradeRequest();
89 UpgradeResponse upgradeResponse = session.getUpgradeResponse();
90 List<HttpCookie> cookies = upgradeRequest.getCookies();
91
92 System.out.println("Upgrade request cookies : " + cookies);
93 String httpSessionId = null;
94 if (cookies != null) {
95 for (HttpCookie cookie : cookies) {
96 if (cookie.getName().equals("JSESSIONID")) {
97 httpSessionId = cookie.getValue();
98 }
99 }
100 }
101
102 if (httpSessionId == null) {
103 HttpSession httpSession = (HttpSession) upgradeRequest.getSession();
104 if (httpSession == null) {
105 // session.disconnect();
106 // return;
107 } else {
108 httpSessionId = httpSession.getId();
109 System.out.println("Upgrade request session ID : " + httpSession.getId());
110 }
111 }
112
113 if (httpSessionId != null) {
114 int dotIdx = httpSessionId.lastIndexOf('.');
115 if (dotIdx > 0) {
116 httpSessionId = httpSessionId.substring(0, dotIdx);
117 }
118 }
119
120 CmsSession cmsSession = getCmsSession(httpSessionId);
121 if (cmsSession == null) {
122 session.disconnect();
123 return;
124 // try {
125 // session.getUpgradeResponse().sendForbidden("Web Sockets must always be authenticated.");
126 // } catch (IOException e) {
127 // e.printStackTrace();
128 // }
129 } else {
130 JsrSession jsrSession = (JsrSession) session;
131 String jsrId = jsrSession.getId();
132 System.out.println("JSR ID: " + jsrId);
133 jsrSession.getUserProperties().put(CmsSession.SESSION_LOCAL_ID, cmsSession.getLocalId());
134 jsrSession.getUserProperties().put(CmsSession.SESSION_UUID, cmsSession.getUuid());
135 jsrSession.getUserProperties().put(HttpContext.REMOTE_USER, cmsSession.getUserDn());
136 // httpSession.setAttribute(HttpContext.AUTHORIZATION,
137 // cmsSession.getAuthorization());
138 }
139 }
140
141 @Override
142 public void onSessionClosed(WebSocketSession session) {
143 // TODO Auto-generated method stub
144
145 }
146 });
147 } catch (ServletException e) {
148 throw new IllegalStateException("Cannot configure web sockets", e);
149 }
150 bc.registerService(javax.websocket.server.ServerContainer.class, serverContainer, null);
151 // ServiceTracker<ServerEndpointConfig.Builder, ServerEndpointConfig.Builder> endpointsTracker = new ServiceTracker<ServerEndpointConfig.Builder, ServerEndpointConfig.Builder>(
152 // bc, ServerEndpointConfig.Builder.class, null) {
153 //
154 // @Override
155 // public ServerEndpointConfig.Builder addingService(
156 // ServiceReference<ServerEndpointConfig.Builder> reference) {
157 //
158 // ServerEndpointConfig.Builder serverEndpointConfig = super.addingService(reference);
159 // try {
160 // serverContainer.addEndpoint(serverEndpointConfig.build());
161 // } catch (DeploymentException e) {
162 // throw new IllegalArgumentException("Cannot add end point " + reference, e);
163 // }
164 // return serverEndpointConfig;
165 // }
166 // };
167 // endpointsTracker.open();
168 // TODO log it properly
169 // TODO close itproperly
170 }
171
172 }
173
174 private CmsSession getCmsSession(String httpSessionId) {
175 if (httpSessionId == null)
176 return null;
177
178 Collection<ServiceReference<CmsSession>> sr;
179 try {
180 sr = bc.getServiceReferences(CmsSession.class,
181 "(" + CmsSession.SESSION_LOCAL_ID + "=" + httpSessionId + ")");
182 } catch (InvalidSyntaxException e) {
183 throw new IllegalStateException("Cannot get CMS session for id " + httpSessionId, e);
184 }
185 if (sr.size() == 1) {
186 CmsSession cmsSession = bc.getService(sr.iterator().next());
187 Authorization authorization = cmsSession.getAuthorization();
188 if (authorization.getName() == null)
189 return null;// anonymous is not sufficient
190 return cmsSession;
191 } else {
192 return null;
193 }
194 }
195
196 }