You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.5 KiB
146 lines
4.5 KiB
const express = require("express");
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const app = express();
|
|
|
|
// Initial Listing Directory
|
|
const listingPath = path.join(__dirname, "public");
|
|
|
|
// index.html path
|
|
const indexPath = path.join(__dirname, "index.html");
|
|
|
|
// Placeholder in your index.html file where dynamic content will be inserted
|
|
const dynamicContentPlaceholder = "<!-- Dynamic Content Placeholder -->";
|
|
|
|
// Function to read the content of the existing "index.html" file
|
|
function readIndexFile() {
|
|
return fs.readFileSync(indexPath, "utf-8");
|
|
}
|
|
|
|
// For any path..
|
|
app.get("*", (req, res) => {
|
|
|
|
const decodedPath = decodeURIComponent(req.path);
|
|
const filePath = path.join(listingPath, decodedPath);
|
|
|
|
// Extract the parent directory
|
|
const parentDirectory = path.join(req.path, '../');
|
|
|
|
// Return nothing if path does not exist
|
|
if (!fs.existsSync(filePath)) {
|
|
return res.status(404).end();
|
|
}
|
|
|
|
// If details of a file directory are returned, create path
|
|
if (fs.statSync(filePath).isDirectory()) {
|
|
// Read contents of directory
|
|
const filesInDir = fs.readdirSync(filePath);
|
|
// For each file in the directory
|
|
// (1) Encode URI for hyperlinks
|
|
// (2) Create HTML for that link
|
|
const links = filesInDir.map(file => {
|
|
const encodedFile = encodeURIComponent(file);
|
|
const fileLink = path.join(req.path, encodedFile);
|
|
|
|
let linkAttributes = "";
|
|
let fileLocationEncoding = ""
|
|
let convertedString = fileLink.replace(/\\/g, '/');
|
|
let icon = ''
|
|
|
|
// Check if the file is of a specific type that should open in a new window/tab
|
|
const fileExtension = path.extname(file).toLowerCase();
|
|
if (isFileTypeToOpenInNewTab(fileExtension)) {
|
|
fileLocationEncoding = 'http://localhost:3000/' + convertedString
|
|
linkAttributes = `onclick="window.open('${fileLocationEncoding}', 'fileWindow', 'width=600,height=400');"`;
|
|
icon = getFileIcon(fileExtension)
|
|
return `<div class='file' ${linkAttributes}>
|
|
<img src='/icons/${icon}'>
|
|
<span class='info-name'>${file}</span>
|
|
</div>`;
|
|
} else {
|
|
return `<a href="${fileLink}" ${linkAttributes}><div class='folder'><img src='/icons/folder.gif'><span class='info-name'>${file}</span></div></a>`;
|
|
}
|
|
|
|
|
|
});
|
|
|
|
// Read the content of the existing "index.html" file
|
|
const indexContent = readIndexFile();
|
|
|
|
// Replace the placeholder with the dynamically generated content
|
|
const finalHtml = indexContent.replace(dynamicContentPlaceholder,
|
|
`<div class='index-cont'><span class='index-txt'>Index of ${req.path}</span>
|
|
<a class='return-cont' href='${parentDirectory === '/' ? '/' : parentDirectory}'>
|
|
<img src='/icons/back.png'>
|
|
<span> Parent Directory </span>
|
|
</a>
|
|
<span class='line-break'></span>
|
|
</div>
|
|
<div class='main-cont'>${links.join("")}</div>`);
|
|
|
|
// Send the modified content as a response
|
|
return res.send(finalHtml);
|
|
|
|
} else {
|
|
|
|
// If its a 'file' type, then open it in a new window
|
|
const fileExtension = path.extname(filePath).toLowerCase();
|
|
|
|
if (fileExtension === ".pdf") {
|
|
// For PDF files, send the file to be displayed in the browser.
|
|
const fileStream = fs.createReadStream(filePath);
|
|
fileStream.pipe(res);
|
|
} else if(fileExtension === ".mp4") {
|
|
const fileStream = fs.createReadStream(filePath);
|
|
res.set("Content-Type", "video/mp4");
|
|
fileStream.pipe(res);
|
|
} else {
|
|
// For other file types, set content type and send file.
|
|
const contentType = getContentType(fileExtension);
|
|
res.set("Content-Type", contentType);
|
|
return res.sendFile(filePath);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Set file icon
|
|
function getFileIcon(fileExtension){
|
|
switch (fileExtension) {
|
|
case ".txt":
|
|
return "generic.gif";
|
|
case ".png":
|
|
return "image2.gif";
|
|
case ".pdf":
|
|
return "text.png"
|
|
case ".mp4":
|
|
return "movie.gif"
|
|
default:
|
|
return "unknown.gif";
|
|
}
|
|
}
|
|
|
|
// Function to get content type based on file extension
|
|
function getContentType(fileExtension) {
|
|
switch (fileExtension) {
|
|
case ".txt":
|
|
return "text/plain";
|
|
case ".png":
|
|
return "image/png";
|
|
case ".mp4":
|
|
return "video/mp4";
|
|
// Add more content types as needed
|
|
default:
|
|
return "application/octet-stream";
|
|
}
|
|
}
|
|
|
|
// Function to check if the file type should open in a new window/tab
|
|
function isFileTypeToOpenInNewTab(fileExtension) {
|
|
const supportedFileTypes = [".pdf", ".png", ".txt", ".mp4"]; // Add more file types as needed
|
|
return supportedFileTypes.includes(fileExtension);
|
|
}
|
|
|
|
const PORT = 3000;
|
|
app.listen(PORT, () => {
|
|
console.log("Server is running on http://localhost:" + PORT);
|
|
});
|
|
|