public Response daemonLogPage(String fileName, Integer start, Integer length, String grep, String user)
            throws IOException, InvalidRequestException {
        Path file = daemonLogRoot.resolve(fileName).toAbsolutePath().normalize();
        if (!file.startsWith(daemonLogRoot) || Paths.get(fileName).getNameCount() != 1) {
            //Prevent fileName from pathing into worker logs, or outside daemon log root 
            return LogviewerResponseBuilder.buildResponsePageNotFound();
        }

        if (file.toFile().exists()) {
            // all types of files included
            List<File> logFiles = Arrays.stream(daemonLogRoot.toFile().listFiles())
                    .filter(File::isFile)
                    .collect(toList());

            List<String> reorderedFilesStr = logFiles.stream()
                    .map(File::getName)
                    .filter(fName -> !StringUtils.equals(fileName, fName))
                    .collect(toList());
            reorderedFilesStr.add(fileName);

            length = length != null ? Math.min(10485760, length) : LogviewerConstant.DEFAULT_BYTES_PER_PAGE;
            final boolean isZipFile = file.getFileName().toString().endsWith(".gz");
            long fileLength = getFileLength(file.toFile(), isZipFile);
            if (start == null) {
                start = Long.valueOf(fileLength - length).intValue();
            }

            String logString = isTxtFile(fileName) ? escapeHtml(pageFile(file.toString(), isZipFile, fileLength, start, length)) :
                    escapeHtml("This is a binary file and cannot display! You may download the full file.");

            List<DomContent> bodyContents = new ArrayList<>();
            if (StringUtils.isNotEmpty(grep)) {
                String matchedString = String.join("\n", Arrays.stream(logString.split("\n"))
                        .filter(str -> str.contains(grep)).collect(toList()));
                bodyContents.add(pre(matchedString).withId("logContent"));
            } else {
                DomContent pagerData = null;
                if (isTxtFile(fileName)) {
                    pagerData = pagerLinks(fileName, start, length, Long.valueOf(fileLength).intValue(), "daemonlog");
                }

                bodyContents.add(searchFileForm(fileName, "yes"));
                // list all daemon logs
                bodyContents.add(logFileSelectionForm(reorderedFilesStr, fileName, "daemonlog"));
                if (pagerData != null) {
                    bodyContents.add(pagerData);
                }
                bodyContents.add(daemonDownloadLink(fileName));
                bodyContents.add(pre(logString).withClass("logContent"));
                if (pagerData != null) {
                    bodyContents.add(pagerData);
                }
            }

            String content = logTemplate(bodyContents, fileName, user).render();
            return LogviewerResponseBuilder.buildSuccessHtmlResponse(content);
        } else {
            return LogviewerResponseBuilder.buildResponsePageNotFound();
        }
    }
@Test
    public void testDaemonLogPageOutsideLogRoot() throws Exception {
        try (TmpPath rootPath = new TmpPath()) {
            LogviewerLogPageHandler handler = createHandlerForTraversalTests(rootPath.getFile().toPath());

            final Response returned = handler.daemonLogPage("../evil.sh", 0, 100, null, "user");

            Utils.forceDelete(rootPath.toString());

            //Should not show files outside daemon log root.
            assertThat(returned.getStatus(), is(Response.Status.NOT_FOUND.getStatusCode()));
        }
    }