File size: 3,301 Bytes
ece4c92
 
 
 
1a7be53
ece4c92
 
 
23bf3a9
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
 
ffe37d1
1a7be53
ffe37d1
1a7be53
ece4c92
 
 
ffe37d1
ece4c92
 
 
 
ffe37d1
ece4c92
 
 
 
ffe37d1
ece4c92
 
 
 
ffe37d1
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
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 HOST_URL = "https://your-domain.com"; // πŸ”Ή Replace with your actual domain
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", () => {
            const servedUrl = `${HOST_URL}/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 ${HOST_URL}:${PORT}`);
});