From 986744dfe7d2a71530fd9a3b443e8d850e2ad062 Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sat, 3 Oct 2020 18:29:09 +0200 Subject: [PATCH] Improve file handling in HLS servlet --- .../main/java/ctbrec/ui/JavaFxRecording.java | 8 +-- .../java/ctbrec/ui/tabs/RecordingsTab.java | 4 +- common/src/main/java/ctbrec/Recording.java | 8 +-- .../ctbrec/recorder/server/HlsServlet.java | 71 ++++++++----------- .../ctbrec/recorder/server/HttpServer.java | 2 +- 5 files changed, 37 insertions(+), 56 deletions(-) diff --git a/client/src/main/java/ctbrec/ui/JavaFxRecording.java b/client/src/main/java/ctbrec/ui/JavaFxRecording.java index f4e7b705..541e9aa3 100644 --- a/client/src/main/java/ctbrec/ui/JavaFxRecording.java +++ b/client/src/main/java/ctbrec/ui/JavaFxRecording.java @@ -162,8 +162,7 @@ public class JavaFxRecording extends Recording { setProgress(updated.getProgress()); setSizeInByte(updated.getSizeInByte()); setSingleFile(updated.isSingleFile()); - getAssociatedFiles().clear(); - getAssociatedFiles().addAll(updated.getAssociatedFiles()); + setAssociatedFiles(updated.getAssociatedFiles()); } @Override @@ -297,11 +296,6 @@ public class JavaFxRecording extends Recording { return delegate.getAssociatedFiles(); } - @Override - public boolean hasContactSheet() { - return delegate.hasContactSheet(); - } - @Override public Optional getContactSheet() { return delegate.getContactSheet(); diff --git a/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java b/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java index b6df182a..e5347bf7 100644 --- a/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java @@ -394,7 +394,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener { MenuItem openContactSheet = new MenuItem("Open contact sheet"); openContactSheet.setOnAction(e -> openContactSheet(first)); - openContactSheet.setDisable(!first.hasContactSheet()); + openContactSheet.setDisable(first.getContactSheet().isEmpty()); contextMenu.getItems().add(openContactSheet); // TODO find a way to reenable this @@ -471,7 +471,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener { DesktopIntegration.open(target); } }); - String url = config.getServerUrl() + "/hls/" + recording.getId() + "/contactsheet.jpg"; + String url = config.getServerUrl() + "/hls/" + recording.getId() + f.getCanonicalPath(); if (config.getSettings().requireAuthentication) { url = UrlUtil.addHmac(url, config); } diff --git a/common/src/main/java/ctbrec/Recording.java b/common/src/main/java/ctbrec/Recording.java index 548ab81b..39770f3b 100644 --- a/common/src/main/java/ctbrec/Recording.java +++ b/common/src/main/java/ctbrec/Recording.java @@ -310,12 +310,12 @@ public class Recording implements Serializable { return getStatus() == FAILED || getStatus() == WAITING || getStatus() == FINISHED; } - public Set getAssociatedFiles() { - return associatedFiles; + protected void setAssociatedFiles(Set associatedFiles) { + this.associatedFiles = associatedFiles; } - public boolean hasContactSheet() { - return getAssociatedFiles().stream().anyMatch(path -> path.endsWith("contactsheet.jpg")); + public Set getAssociatedFiles() { + return associatedFiles; } public Optional getContactSheet() { diff --git a/server/src/main/java/ctbrec/recorder/server/HlsServlet.java b/server/src/main/java/ctbrec/recorder/server/HlsServlet.java index c1776852..43c61233 100644 --- a/server/src/main/java/ctbrec/recorder/server/HlsServlet.java +++ b/server/src/main/java/ctbrec/recorder/server/HlsServlet.java @@ -4,11 +4,8 @@ import static javax.servlet.http.HttpServletResponse.*; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; -import java.nio.file.Path; -import java.nio.file.Paths; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import java.util.Enumeration; import java.util.Objects; import java.util.Optional; import java.util.regex.Matcher; @@ -22,7 +19,6 @@ import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ctbrec.Config; import ctbrec.Recording; import ctbrec.recorder.Recorder; @@ -30,12 +26,9 @@ public class HlsServlet extends AbstractCtbrecServlet { private static final transient Logger LOG = LoggerFactory.getLogger(HlsServlet.class); - private final Config config; - private Recorder recorder; - public HlsServlet(Config config, Recorder recorder) { - this.config = config; + public HlsServlet(Recorder recorder) { this.recorder = recorder; } @@ -43,45 +36,39 @@ public class HlsServlet extends AbstractCtbrecServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String contextPath = getServletContext().getContextPath(); String request = req.getRequestURI().substring(contextPath.length() + 5); - Path recordingsDirPath = Paths.get(config.getSettings().recordingsDir).toAbsolutePath().normalize(); - Path requestedFilePath = recordingsDirPath.resolve(request).toAbsolutePath().normalize(); - File requestedFile = requestedFilePath.toFile(); try { - if (requestedFile.getName().equals("playlist.m3u8")) { - boolean isRequestAuthenticated = checkAuthentication(req, req.getRequestURI()); - if (!isRequestAuthenticated) { - writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"HMAC does not match\"}"); - return; - } + String id = request.split("/")[0]; + Optional rec = getRecordingById(id); + if (!rec.isPresent()) { + error404(req, resp); + return; + } - String id = request.substring(0, request.indexOf('/')); - Optional rec = getRecordingById(id); - if (rec.isPresent()) { + String requestedFilePath; + File requestFile; + boolean idOnly = request.indexOf('/') < 0; + if (idOnly) { + requestFile = rec.get().getPostProcessedFile(); + requestedFilePath = requestFile.getCanonicalPath(); + } else { + requestedFilePath = request.substring(request.indexOf('/')); + requestFile = new File(requestedFilePath); + } + + if (rec.get().getAssociatedFiles().contains(requestedFilePath)) { + serveSegment(req, resp, requestFile); + } else { + if (requestFile.getName().equals("playlist.m3u8")) { + boolean isRequestAuthenticated = checkAuthentication(req, req.getRequestURI()); + if (!isRequestAuthenticated) { + writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"HMAC does not match\"}"); + return; + } servePlaylist(req, resp, rec.get().getAbsoluteFile()); } else { - error404(req, resp); - return; - } - } else { - String id = request.split("/")[0]; - Optional rec = getRecordingById(id); - if (rec.isPresent()) { - File path = rec.get().getAbsoluteFile(); - if (!path.isFile()) { - path = new File(path, requestedFile.getName()); - } - if (LOG.isTraceEnabled()) { - Enumeration headerNames = req.getHeaderNames(); - while (headerNames.hasMoreElements()) { - String header = headerNames.nextElement(); - LOG.trace("{}: {}", header, req.getHeader(header)); - } - } - serveSegment(req, resp, path); - } else { - error404(req, resp); - return; + requestFile = new File(rec.get().getAbsoluteFile(), requestedFilePath); + serveSegment(req, resp, requestFile); } } } catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) { diff --git a/server/src/main/java/ctbrec/recorder/server/HttpServer.java b/server/src/main/java/ctbrec/recorder/server/HttpServer.java index fc354de5..aae3cf07 100644 --- a/server/src/main/java/ctbrec/recorder/server/HttpServer.java +++ b/server/src/main/java/ctbrec/recorder/server/HttpServer.java @@ -213,7 +213,7 @@ public class HttpServer { holder = new ServletHolder(configServlet); defaultContext.addServlet(holder, "/config"); - HlsServlet hlsServlet = new HlsServlet(this.config, recorder); + HlsServlet hlsServlet = new HlsServlet(recorder); holder = new ServletHolder(hlsServlet); defaultContext.addServlet(holder, "/hls/*");