File size: 3,117 Bytes
ece4c92
 
 
 
1a7be53
ece4c92
 
 
 
 
 
 
1a7be53
ece4c92
 
1a7be53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ece4c92
 
 
 
 
 
 
 
 
1a7be53
ece4c92
1a7be53
 
ece4c92
 
1a7be53
 
 
 
 
ece4c92
 
1a7be53
 
 
ece4c92
1a7be53
ece4c92
1a7be53
ece4c92
 
1a7be53
 
 
ece4c92
 
 
 
 
 
 
 
1a7be53
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
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
const scheduleFileDeletion = (filePath, delay = 600000) => { // 10 minutes
    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 = `http://localhost:${PORT}/files/${filename}`;
            scheduleFileDeletion(filePath); // Auto-delete after 10 minutes
            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
app.use("/files", express.static(DOWNLOAD_DIR));

// Start the server
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});