File size: 3,355 Bytes
ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 1a7be53 ffe37d1 1a7be53 ffe37d1 1a7be53 ffe37d1 1a7be53 ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 c6e5396 1a7be53 ffe37d1 1a7be53 ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 c6e5396 ece4c92 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
const express = require("express");
const axios = require("axios");
const fs = require("fs");
const path = require("path");
const https = require("https");
const app = express();
const PORT = 7860;
const DOWNLOAD_DIR = path.join(__dirname, "downloads");
// Ensure the downloads directory exists
if (!fs.existsSync(DOWNLOAD_DIR)) {
fs.mkdirSync(DOWNLOAD_DIR, { recursive: true });
}
// Axios instance to ignore SSL certificate verification
const axiosInstance = axios.create({
httpsAgent: new https.Agent({ rejectUnauthorized: false })
});
// Function to extract filename from URL or headers
const getFileName = (fileUrl, headers) => {
let filename = path.basename(new URL(fileUrl).pathname);
if (headers["content-disposition"]) {
const match = headers["content-disposition"].match(/filename="(.+)"/);
if (match) {
filename = match[1];
}
}
return filename.replace(/[<>:"/\\|?*]+/g, ""); // Remove invalid characters
};
// Function to delete file after a delay (default: 10 minutes)
const scheduleFileDeletion = (filePath, delay = 600000) => {
setTimeout(() => {
fs.unlink(filePath, (err) => {
if (!err) {
console.log(`β
Deleted file: ${filePath}`);
}
});
}, delay);
};
// API Route to download and serve .mkv files
app.get("/download", async (req, res) => {
const fileUrl = req.query.url;
if (!fileUrl) {
return res.status(400).json({ error: "β Missing URL parameter" });
}
try {
console.log(`β¬οΈ Downloading: ${fileUrl}`);
// Request file with forced download handling
const response = await axiosInstance({
url: fileUrl,
method: "GET",
responseType: "stream",
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "*/*"
}
});
// Extract correct filename
const filename = getFileName(fileUrl, response.headers);
const filePath = path.join(DOWNLOAD_DIR, filename);
// Pipe response stream to file
const writer = fs.createWriteStream(filePath);
response.data.pipe(writer);
writer.on("finish", () => {
// Dynamically get the host URL from request headers
const hostUrl = `${req.protocol}://${req.get("host")}`;
const servedUrl = `${hostUrl}/files/${filename}`;
scheduleFileDeletion(filePath); // Auto-delete after 10 minutes
console.log(`β
Download complete: ${servedUrl}`);
return res.json({ message: "Download complete", fileUrl: servedUrl });
});
writer.on("error", (err) => {
console.error("β Error writing file:", err);
return res.status(500).json({ error: "Error saving file" });
});
} catch (error) {
console.error("β Download error:", error.message);
return res.status(500).json({ error: "Failed to download file" });
}
});
// Serve files from downloads directory (publicly accessible)
app.use("/files", express.static(DOWNLOAD_DIR));
// Start the server
app.listen(PORT, () => {
console.log(`π Server running on port ${PORT}`);
}); |