File size: 4,355 Bytes
6279ff0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// === 引入依赖 ===
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const requestIp = require('request-ip');
const crypto = require('crypto'); // 用于生成设备指纹的哈希值
const { URL } = require('url'); // 用于验证 URL 格式

const app = express();

// === 配置常量 ===
const PORT = process.env.PORT || 7777; // 默认监听端口 7777
const HOST = '0.0.0.0';               // 允许来自外部的连接

// === 中间件配置 ===

// CORS 配置
const corsOptions = {
    origin: '*', // 允许所有来源的请求
    methods: ['GET', 'POST', 'OPTIONS'],
    allowedHeaders: ['Content-Type'],
};
app.use(cors(corsOptions));

// 使用 Body-Parser 解析 JSON 请求体
app.use(bodyParser.json());

// 使用 request-ip 中间件获取客户端 IP
app.use(requestIp.mw());

// === 内存存储及清理 ===

// URL 存储字典(以用户唯一标识符为键)
const urlMap = new Map();

// 超时时间配置(以毫秒为单位)
const EXPIRATION_TIME = 90 * 1000; // 90 秒
const CLEANUP_INTERVAL = 60 * 1000; // 每 60 秒清理一次

// 定时清理过期数据
setInterval(() => {
    const now = Date.now();
    const expiredTime = now - EXPIRATION_TIME;

    for (const [userId, { timestamp }] of urlMap) {
        if (timestamp < expiredTime) {
            console.log(`Deleting expired data for user: ${userId}`);
            urlMap.delete(userId); // 删除过期数据
        }
    }
}, CLEANUP_INTERVAL);

// === 辅助函数 ===

// 生成设备指纹
const generateDeviceFingerprint = (req) => {
    const ip = req.clientIp || '';
    const userAgent = req.headers['user-agent'] || '';
    const acceptLanguage = req.headers['accept-language'] || '';
    const connection = req.headers['connection'] || '';
    const encoding = req.headers['accept-encoding'] || '';
    const forwardedFor = req.headers['x-forwarded-for'] || '';

    // 将关键信息合并生成唯一指纹
    const rawFingerprint = `${ip}-${userAgent}-${acceptLanguage}-${connection}-${encoding}-${forwardedFor}`;

    // 使用 SHA-256 哈希算法生成指纹
    const fingerprint = crypto.createHash('sha256').update(rawFingerprint).digest('hex');
    return fingerprint;
};

// === 路由 ===

// 存储 URL(POST 请求)
app.post('/storeURL', (req, res) => {
    const url = req.body.url; // 从请求体中解析 URL
    const ip = req.clientIp; // 获取客户端 IP

    // 验证 URL 是否存在并合法
    if (!url) {
        return res.status(400).json({ error: 'URL is required.' });
    }
    try {
        new URL(url); // 验证 URL 格式
    } catch (err) {
        return res.status(400).json({ error: 'Invalid URL format.' });
    }

    // 生成用户唯一标识符(包括 IP 和设备指纹)
    const deviceFingerprint = generateDeviceFingerprint(req);
    const userId = `${ip}-${deviceFingerprint}`; // 结合 IP 和设备指纹生成唯一标识符

    // 存储到字典中
    urlMap.set(userId, { url, timestamp: Date.now() });
    console.log(`Stored URL for user: ${userId}`);

    // 返回成功响应
    res.json({ message: 'URL stored successfully.', userId });
});

// 获取 URL(GET 请求)
app.get('/getURL', (req, res) => {
    const ip = req.clientIp; // 获取客户端 IP

    // 生成用户唯一标识符(包括 IP 和设备指纹)
    const deviceFingerprint = generateDeviceFingerprint(req);
    const userId = `${ip}-${deviceFingerprint}`;

    // 查询字典获取存储的 URL
    if (urlMap.has(userId)) {
        const storedData = urlMap.get(userId);
        storedData.timestamp = Date.now(); // 更新数据时间戳
        urlMap.set(userId, storedData); // 保存更新后的数据

        console.log(`Retrieved URL for user: ${userId}`);
        return res.json({ url: storedData.url });
    } else {
        console.error(`No URL found for user: ${userId}`);
        return res.status(404).json({ error: 'URL not found for this user.' });
    }
});

// 测试路由
app.get("/", (req, res) => {
    res.send("Welcome to the URL Server! The server is running.");
});

// === 启动服务器 ===
app.listen(PORT, HOST, (err) => {
    if (err) {
        console.error(`Error starting server: ${err}`);
        return;
    }
    console.log(`Server running on http://${HOST}:${PORT}`);
});