CatPtain commited on
Commit
6acb2cb
·
verified ·
1 Parent(s): 1e6a865

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +65 -29
server.js CHANGED
@@ -3,8 +3,8 @@ const express = require('express');
3
  const bodyParser = require('body-parser');
4
  const cors = require('cors');
5
  const requestIp = require('request-ip');
6
- const crypto = require('crypto');
7
- const { URL } = require('url');
8
 
9
  const app = express();
10
 
@@ -14,21 +14,31 @@ const HOST = '0.0.0.0';
14
  console.log(`Starting server! PORT: ${PORT}`);
15
 
16
  // === 中间件配置 ===
 
 
17
  const corsOptions = {
18
- origin: '*',
19
  methods: ['GET', 'POST', 'OPTIONS'],
20
  allowedHeaders: ['Content-Type'],
21
  };
22
  app.use(cors(corsOptions));
 
 
23
  app.use(bodyParser.json());
 
 
24
  app.use(requestIp.mw());
25
 
26
- // === 内存存储 ===
 
 
27
  const urlMap = new Map();
 
 
28
  const EXPIRATION_TIME = 90 * 1000; // 90 秒
29
- const CLEANUP_INTERVAL = 60 * 1000;
30
 
31
- // 定期清理任务
32
  setInterval(() => {
33
  const now = Date.now();
34
  const expiredTime = now - EXPIRATION_TIME;
@@ -36,56 +46,82 @@ setInterval(() => {
36
  for (const [userId, { timestamp }] of urlMap) {
37
  if (timestamp < expiredTime) {
38
  console.log(`Deleting expired data for user: ${userId}`);
39
- urlMap.delete(userId);
40
  }
41
  }
42
  }, CLEANUP_INTERVAL);
43
 
44
- // === 路由 ===
45
-
46
  // 健康检查
47
  app.get("/", (req, res) => {
48
  res.status(200).send({ message: "Server is healthy and running." });
49
  });
50
 
51
- // 存储 URL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  app.post('/storeURL', (req, res) => {
53
- const url = req.body.url;
54
- const ip = req.clientIp;
55
 
 
56
  if (!url) {
57
- return res.status(400).json({ success: false, message: 'URL is required.' });
58
  }
59
  try {
60
- new URL(url);
61
  } catch (err) {
62
- return res.status(400).json({ success: false, message: 'Invalid URL format.' });
63
  }
64
 
65
- const fingerprint = crypto.createHash('sha256').update(`${ip}-${req.headers['user-agent']}`).digest('hex');
66
- const userId = `${ip}-${fingerprint}`;
67
- urlMap.set(userId, { url, timestamp: Date.now() });
68
 
 
 
69
  console.log(`Stored URL for user: ${userId}`);
70
- res.json({ success: true, message: 'URL stored successfully.', userId });
 
 
71
  });
72
 
73
- // 获取 URL
74
  app.get('/getURL', (req, res) => {
75
- const ip = req.clientIp;
76
- const fingerprint = crypto.createHash('sha256').update(`${ip}-${req.headers['user-agent']}`).digest('hex');
77
- const userId = `${ip}-${fingerprint}`;
78
 
 
 
 
 
 
79
  if (urlMap.has(userId)) {
80
  const storedData = urlMap.get(userId);
81
- storedData.timestamp = Date.now();
82
- urlMap.set(userId, storedData);
83
 
84
  console.log(`Retrieved URL for user: ${userId}`);
85
- res.json({ success: true, url: storedData.url });
86
  } else {
87
  console.error(`No URL found for user: ${userId}`);
88
- res.status(404).json({ success: false, message: 'URL not found for this user.' });
89
  }
90
  });
91
 
@@ -93,7 +129,7 @@ app.get('/getURL', (req, res) => {
93
  app.listen(PORT, HOST, (err) => {
94
  if (err) {
95
  console.error(`Error starting server: ${err}`);
96
- process.exit(1);
97
  }
98
  console.log(`Server running on http://${HOST}:${PORT}`);
99
  });
@@ -105,4 +141,4 @@ process.on('uncaughtException', (err) => {
105
 
106
  process.on('unhandledRejection', (reason, promise) => {
107
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
108
- });
 
3
  const bodyParser = require('body-parser');
4
  const cors = require('cors');
5
  const requestIp = require('request-ip');
6
+ const crypto = require('crypto'); // 用于生成设备指纹的哈希值
7
+ const { URL } = require('url'); // 用于验证 URL 格式
8
 
9
  const app = express();
10
 
 
14
  console.log(`Starting server! PORT: ${PORT}`);
15
 
16
  // === 中间件配置 ===
17
+
18
+ // CORS 配置
19
  const corsOptions = {
20
+ origin: '*', // 允许所有来源的请求
21
  methods: ['GET', 'POST', 'OPTIONS'],
22
  allowedHeaders: ['Content-Type'],
23
  };
24
  app.use(cors(corsOptions));
25
+
26
+ // 使用 Body-Parser 解析 JSON 请求体
27
  app.use(bodyParser.json());
28
+
29
+ // 使用 request-ip 中间件获取客户端 IP
30
  app.use(requestIp.mw());
31
 
32
+ // === 内存存储及清理 ===
33
+
34
+ // URL 存储字典(以用户唯一标识符为键)
35
  const urlMap = new Map();
36
+
37
+ // 超时时间配置(以毫秒为单位)
38
  const EXPIRATION_TIME = 90 * 1000; // 90 秒
39
+ const CLEANUP_INTERVAL = 60 * 1000; // 每 60 秒清理一次
40
 
41
+ // 定时清理过期数据
42
  setInterval(() => {
43
  const now = Date.now();
44
  const expiredTime = now - EXPIRATION_TIME;
 
46
  for (const [userId, { timestamp }] of urlMap) {
47
  if (timestamp < expiredTime) {
48
  console.log(`Deleting expired data for user: ${userId}`);
49
+ urlMap.delete(userId); // 删除过期数据
50
  }
51
  }
52
  }, CLEANUP_INTERVAL);
53
 
 
 
54
  // 健康检查
55
  app.get("/", (req, res) => {
56
  res.status(200).send({ message: "Server is healthy and running." });
57
  });
58
 
59
+ // === 辅助函数 ===
60
+ // 生成设备指纹
61
+ const generateDeviceFingerprint = (req) => {
62
+ const ip = req.clientIp || '';
63
+ const userAgent = req.headers['user-agent'] || '';
64
+ const acceptLanguage = req.headers['accept-language'] || '';
65
+ const connection = req.headers['connection'] || '';
66
+ const encoding = req.headers['accept-encoding'] || '';
67
+ const forwardedFor = req.headers['x-forwarded-for'] || '';
68
+
69
+ // 将关键信息合并生成唯一指纹
70
+ const rawFingerprint = `${ip}-${userAgent}-${acceptLanguage}-${connection}-${encoding}-${forwardedFor}`;
71
+
72
+ // 使用 SHA-256 哈希算法生成指纹
73
+ const fingerprint = crypto.createHash('sha256').update(rawFingerprint).digest('hex');
74
+ return fingerprint;
75
+ };
76
+
77
+ // === 路由 ===
78
+
79
+ // 存储 URL(POST 请求)
80
  app.post('/storeURL', (req, res) => {
81
+ const url = req.body.url; // 从请求体中解析 URL
82
+ const ip = req.clientIp; // 获取客户端 IP
83
 
84
+ // 验证 URL 是否存在并合法
85
  if (!url) {
86
+ return res.status(400).json({ error: 'URL is required.' });
87
  }
88
  try {
89
+ new URL(url); // 验证 URL 格式
90
  } catch (err) {
91
+ return res.status(400).json({ error: 'Invalid URL format.' });
92
  }
93
 
94
+ // 生成用户唯一标识符(包括 IP 和设备指纹)
95
+ const deviceFingerprint = generateDeviceFingerprint(req);
96
+ const userId = `${ip}-${deviceFingerprint}`; // 结合 IP 和设备指纹生成唯一标识符
97
 
98
+ // 存储到字典中
99
+ urlMap.set(userId, { url, timestamp: Date.now() });
100
  console.log(`Stored URL for user: ${userId}`);
101
+
102
+ // 返回成功响应
103
+ res.json({ message: 'URL stored successfully.', userId });
104
  });
105
 
106
+ // 获取 URL(GET 请求)
107
  app.get('/getURL', (req, res) => {
108
+ const ip = req.clientIp; // 获取客户端 IP
 
 
109
 
110
+ // 生成用户唯一标识符(包括 IP 和设备指纹)
111
+ const deviceFingerprint = generateDeviceFingerprint(req);
112
+ const userId = `${ip}-${deviceFingerprint}`;
113
+
114
+ // 查询字典获取存储的 URL
115
  if (urlMap.has(userId)) {
116
  const storedData = urlMap.get(userId);
117
+ storedData.timestamp = Date.now(); // 更新数据时间戳
118
+ urlMap.set(userId, storedData); // 保存更新后的数据
119
 
120
  console.log(`Retrieved URL for user: ${userId}`);
121
+ return res.json({ url: storedData.url });
122
  } else {
123
  console.error(`No URL found for user: ${userId}`);
124
+ return res.status(404).json({ error: 'URL not found for this user.' });
125
  }
126
  });
127
 
 
129
  app.listen(PORT, HOST, (err) => {
130
  if (err) {
131
  console.error(`Error starting server: ${err}`);
132
+ return;
133
  }
134
  console.log(`Server running on http://${HOST}:${PORT}`);
135
  });
 
141
 
142
  process.on('unhandledRejection', (reason, promise) => {
143
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
144
+ });