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;
}
}