package com.aimmac23.hub.servlet; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.exec.StreamPumper; import org.apache.http.HttpStatus; import org.openqa.grid.internal.ExternalSessionKey; import com.aimmac23.hub.HubVideoRegistry; import com.aimmac23.hub.videostorage.StoredVideoDownloadContext; import com.aimmac23.hub.videostorage.StoredVideoInfoContext; /** * A servlet to download videos for a given sessionId. * * Note that videos are not available until you have closed the Selenium Session * (calling driver.quit(), for example). * * @author Alasdair Macmillan * */ public class HubVideoDownloadServlet extends AbstractHubVideoServlet { private static final Logger log = Logger.getLogger(HubVideoDownloadServlet.class.getName()); private static final long serialVersionUID = 1L; static { try { // force this class to be initialized, so any errors are thrown at startup instead of first use Class.forName(HubVideoRegistry.class.getCanonicalName()); } catch (ClassNotFoundException e) { // Can't happen } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sessionId = req.getParameter("sessionId"); if(sessionId == null) { resp.setStatus(HttpStatus.SC_BAD_REQUEST); resp.getWriter().write("Missing parameter: 'sessionId'"); return; } if(!checkValidSessionId(sessionId, resp)) { // response writing already handled return; } StoredVideoDownloadContext videoContext; try { videoContext = HubVideoRegistry.getVideoForSession(new ExternalSessionKey(sessionId)); } catch (Exception e) { log.log(Level.WARNING, "Caught exception when fetching video for " + sessionId, e); resp.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); resp.getWriter().write("Internal error when fetching video"); return; } if(!videoContext.isVideoFound()) { resp.setStatus(HttpStatus.SC_NOT_FOUND); resp.getWriter().write("Video content not found for sessionId: " + sessionId); videoContext.close(); log.info("Received request for video that was not found. Requested sessionId: " + sessionId); return; } try { log.info("Received request for video - now returning content. Requested sessionId: " + sessionId); resp.setContentType("video/webm"); Long contentLength = videoContext.getContentLengthIfKnown(); if(contentLength != null) { resp.setContentLength(contentLength.intValue()); } new StreamPumper(videoContext.getStream(), resp.getOutputStream()).run(); return; } finally { videoContext.close(); } } @Override protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sessionId = req.getParameter("sessionId"); if(sessionId == null) { resp.setStatus(HttpStatus.SC_BAD_REQUEST); return; } StoredVideoInfoContext videoInfoForSession; try { videoInfoForSession = HubVideoRegistry.getVideoInfoForSession(new ExternalSessionKey(sessionId)); } catch (Exception e) { log.log(Level.WARNING, "Caught exception when fetching video information for " + sessionId, e); resp.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); resp.getWriter().write("Internal error when fetching video information"); return; } if(!videoInfoForSession.isVideoFound()) { resp.setStatus(HttpStatus.SC_NOT_FOUND); return; } resp.setStatus(HttpStatus.SC_OK); resp.setContentType("video/mp4"); if(videoInfoForSession.getContentLengthIfKnown() != null) { resp.setContentLength(videoInfoForSession.getContentLengthIfKnown().intValue()); } return; } }