1 17 package com.sslexplorer.vfs.webdav; 18 19 import java.io.IOException ; 20 import java.util.ArrayList ; 21 import java.util.Enumeration ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 25 import javax.servlet.Servlet ; 26 import javax.servlet.ServletConfig ; 27 import javax.servlet.ServletContext ; 28 import javax.servlet.ServletException ; 29 import javax.servlet.ServletRequest ; 30 import javax.servlet.ServletResponse ; 31 import javax.servlet.http.HttpServletRequest ; 32 import javax.servlet.http.HttpServletResponse ; 33 import javax.servlet.http.HttpSessionBindingEvent ; 34 import javax.servlet.http.HttpSessionBindingListener ; 35 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 import org.apache.struts.Globals; 39 import org.apache.struts.action.ActionMessages; 40 import org.apache.struts.util.MessageResources; 41 42 import com.sslexplorer.core.BundleActionMessage; 43 import com.sslexplorer.core.CoreException; 44 import com.sslexplorer.core.CoreUtil; 45 import com.sslexplorer.policyframework.LaunchSession; 46 import com.sslexplorer.properties.PropertyProfile; 47 import com.sslexplorer.security.Constants; 48 import com.sslexplorer.security.LogonControllerFactory; 49 import com.sslexplorer.security.SecurityErrorException; 50 import com.sslexplorer.security.SessionInfo; 51 import com.sslexplorer.security.User; 52 import com.sslexplorer.vfs.VFSRepository; 53 import com.sslexplorer.vfs.VFSResource; 54 55 69 public class DAVServlet implements Servlet , DAVListener { 70 71 final static Log log = LogFactory.getLog(DAVServlet.class); 72 73 77 private static String PROCESSOR_ATTR = "davServlet.processor"; 78 79 84 private static String SESSION_INVALIDATE_LISTENER_ATTR = "davServlet.sessionInvalidateListener"; 85 86 91 private static String SIGNATURE = DAVUtilities.getProperty("servlet.signature") + '/' + DAVUtilities.getProperty("version"); 92 97 private static String INFORMATION = DAVUtilities.getProperty("servlet.information") + " version " 98 + DAVUtilities.getProperty("version"); 99 104 private ServletContext context = null; 105 110 private ServletConfig config = null; 111 116 private static List processors = new ArrayList (); 117 118 123 public DAVServlet() { 124 super(); 125 } 126 127 160 public void init(ServletConfig config) throws ServletException { 161 162 this.context = config.getServletContext(); 163 this.config = config; 164 165 } 166 167 172 public void destroy() { 173 for (Iterator i = processors.iterator(); i.hasNext();) { 174 ((DAVProcessor) i.next()).getRepository().removeListener(this); 175 } 176 } 177 178 183 public ServletConfig getServletConfig() { 184 return (this.config); 185 } 186 187 192 public ServletContext getServletContext() { 193 return (this.context); 194 } 195 196 201 public String getServletInfo() { 202 return INFORMATION; 203 } 204 205 public static DAVSession updateDAVSession(HttpServletRequest request, String resourcePath) { 206 209 request.getSession().setAttribute("com.sslexplorer.vfs.webdav.DAVMethod", request.getSession().getId()); 210 DAVSession webdavSession = DAVSessionStore.getInstance().getSession(request.getSession().getId()); 211 if (webdavSession == null) { 212 webdavSession = new DAVSession(request.getSession().getId()); 213 DAVSessionStore.getInstance().addSession(webdavSession); 214 } 215 PropertyProfile profile = (PropertyProfile) request.getSession().getAttribute(Constants.SELECTED_PROFILE); 216 if (profile != null) { 217 webdavSession.setAttribute(DAVSession.ATTR_PROFILE, profile); 218 } 219 try { 220 User user = LogonControllerFactory.getInstance().getUser(request); 221 if (user != null) { 222 webdavSession.setAttribute(DAVSession.ATTR_USER, user); 223 } 224 } catch (SecurityErrorException e1) { 225 } 226 if (resourcePath != null) { 227 webdavSession.setAttribute(DAVSession.ATTR_RESOURCE_PATH, resourcePath); 228 } 229 return webdavSession; 230 } 231 232 public static DAVProcessor getDAVProcessor(HttpServletRequest req) throws CoreException, Exception { 233 SessionInfo session = LogonControllerFactory.getInstance().getSessionInfo(req); 234 return getDAVProcessor(session); 235 } 236 237 public static DAVProcessor getDAVProcessor(SessionInfo session) throws Exception { 238 DAVProcessor processor = (DAVProcessor) session.getHttpSession().getAttribute(PROCESSOR_ATTR); 239 if (processor == null) { 240 VFSRepository repository = VFSRepository.getRepository(session); 241 processor = new DAVProcessor(repository, session); 242 processors.add(processor); 243 session.getHttpSession().setAttribute(PROCESSOR_ATTR, processor); 244 session.getHttpSession().setAttribute(SESSION_INVALIDATE_LISTENER_ATTR, new SessionInvalidateListener(processor)); 245 if (log.isInfoEnabled()) 246 log.info("Initialized repository"); 247 } 248 return processor; 249 } 250 251 public static VFSResource getDAVResource(LaunchSession launchSession, HttpServletRequest request, HttpServletResponse response, String path) 252 throws DAVBundleActionMessageException, Exception { 253 VFSResource res = null; 254 try { 255 DAVProcessor processor = getDAVProcessor(request); 256 DAVTransaction transaction = new DAVTransaction(request, response); 257 res = processor.getRepository().getResource(launchSession, path, transaction.getCredentials()); 258 res.verifyAccess(); 260 } catch (DAVAuthenticationRequiredException e) { 261 DAVServlet.sendAuthorizationError(request, response, e.getHttpRealm()); 262 throw e; 263 } 264 return res; 265 } 266 267 272 public void service(ServletRequest request, ServletResponse response) throws ServletException , IOException { 273 HttpServletRequest req = (HttpServletRequest ) request; 274 HttpServletResponse res = (HttpServletResponse ) response; 275 276 if (System.getProperty("sslexplorer.webdav.debug", "false").equalsIgnoreCase("true")) { 277 for (Enumeration e = req.getHeaderNames(); e.hasMoreElements();) { 278 String header = (String ) e.nextElement(); 279 for (Enumeration e2 = req.getHeaders(header); e2.hasMoreElements();) { 280 log.info(header + ": " + (String ) e2.nextElement()); 281 } 282 } 283 } 284 285 if (log.isDebugEnabled()) 286 log.debug("Processing " + req.getMethod() + " " + req.getPathInfo()); 287 288 DAVTransaction transaction = new DAVTransaction(req, res); 289 290 try { 291 292 if (transaction.verifyAuthorization()) { 293 DAVServlet.updateDAVSession(req, transaction.getPath()); 294 295 DAVProcessor processor = null; 296 try { 297 processor = DAVServlet.getDAVProcessor(req); 298 } catch (CoreException e) { 299 ActionMessages mesgs = (ActionMessages) request.getAttribute(Globals.ERROR_KEY); 300 if (mesgs == null) { 301 mesgs = new ActionMessages(); 302 request.setAttribute(Globals.ERROR_KEY, mesgs); 303 } 304 mesgs.add(Globals.MESSAGE_KEY, e.getBundleActionMessage()); 305 return; 306 } catch (Exception e1) { 307 throw new IOException (e1.getMessage()); 308 } 309 310 315 316 res.setHeader("Server", this.context.getServerInfo() + ' ' + SIGNATURE); 317 res.setHeader("MS-Author-Via", "DAV"); 318 res.setHeader("DAV", "1"); 319 320 SessionInfo sessionInfo = transaction.getSessionInfo(); 321 int timeoutId = sessionInfo == null ? -1 : LogonControllerFactory.getInstance() 322 .addSessionTimeoutBlock(transaction.getSessionInfo().getHttpSession(), "DAV Transaction"); 323 ; 324 try { 325 processor.process(transaction); 326 } finally { 327 if (timeoutId != -1) 328 LogonControllerFactory.getInstance().removeSessionTimeoutBlock(transaction.getSessionInfo() 329 .getHttpSession(), 330 timeoutId); 331 } 332 } 333 } catch (DAVRedirection redir) { 334 String redirPath = "/fs" + redir.getLocation().getFullPath(); 335 req.getRequestDispatcher(redirPath).forward(req, res); 336 } catch (DAVAuthenticationRequiredException e) { 337 sendAuthorizationError(req, res, e.getHttpRealm()); 340 } catch(DAVBundleActionMessageException ex) { 341 log.error("Network Places Request Failed: " + req.getPathInfo(), ex); 342 BundleActionMessage bam = ex.getBundleActionMessage(); 343 MessageResources mr = CoreUtil.getMessageResources(req.getSession(), bam.getBundle()); 344 String val = mr == null ? null : mr.getMessage(bam.getKey()); 346 res.sendError(DAVStatus.SC_INTERNAL_SERVER_ERROR, 347 val == null ? ( ex.getMessage() == null ? "No message supplied." : ex.getMessage()) : val); 348 } catch (DAVException ex) { 349 res.setStatus(ex.getStatus()); 350 } catch (LockedException ex) { 351 res.sendError(DAVStatus.SC_LOCKED, ex.getMessage()); 352 } catch (Throwable t) { 353 log.error("Network Places Request Failed: " + req.getPathInfo(), t); 354 res.sendError(DAVStatus.SC_INTERNAL_SERVER_ERROR, t.getMessage() == null ? "<null>" : t.getMessage()); 355 } 356 } 357 358 private boolean isWebDAVMethod(HttpServletRequest request) { 359 return 360 361 366 367 !request.getMethod().equalsIgnoreCase("head") && !request.getMethod().equalsIgnoreCase("post"); 369 } 370 371 public static void sendAuthorizationError(HttpServletRequest request, HttpServletResponse response, String realm) 372 throws IOException { 373 if (log.isDebugEnabled()) 374 log.debug("Sending auth request for realm " + realm); 375 response.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\""); 376 response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 377 } 378 379 385 public void notify(VFSResource resource, int event) { 386 String message = "Unknown event"; 387 switch (event) { 388 case DAVListener.COLLECTION_CREATED: 389 message = "Collection created"; 390 break; 391 case DAVListener.COLLECTION_REMOVED: 392 message = "Collection removed"; 393 break; 394 case DAVListener.RESOURCE_CREATED: 395 message = "Resource created"; 396 break; 397 case DAVListener.RESOURCE_REMOVED: 398 message = "Resource removed"; 399 break; 400 case DAVListener.RESOURCE_MODIFIED: 401 message = "Resource modified"; 402 break; 403 } 404 if (log.isDebugEnabled()) 405 log.debug(message + ": \"" + resource.getRelativePath() + "\""); 406 } 407 408 static class SessionInvalidateListener implements HttpSessionBindingListener { 409 410 private DAVProcessor processor; 411 412 415 SessionInvalidateListener(DAVProcessor processor) { 416 this.processor = processor; 417 } 418 419 424 public void valueBound(HttpSessionBindingEvent arg0) { 425 } 426 427 432 public void valueUnbound(HttpSessionBindingEvent arg0) { 433 processors.remove(processor); 434 } 436 437 } 438 } 439 | Popular Tags |