CoolFace
Apppublic

CatPtain/url_server

sourceHugging Facemitupdated 2y agoView on Hugging Face
0likes
server.js159 linesDownload Raw Back to root
1// === 全局异常处理(放在顶部) ===2process.on('uncaughtException', (err) => {3    console.error('[Fatal Error] Uncaught Exception:', err.stack || err.message || err);4    process.exit(1); // 可选择退出服务进程5});6 7process.on('unhandledRejection', (reason, promise) => {8    console.error('[Warning] Unhandled Rejection at:', promise, 'reason:', reason);9});10 11// === 引入依赖 ===12const express = require('express');13const bodyParser = require('body-parser');14const cors = require('cors');15const requestIp = require('request-ip');16const crypto = require('crypto'); // 用于生成设备指纹的哈希值17const { URL } = require('url');  // 用于验证 URL 格式18 19const app = express();20 21// === 配置常量 ===22const PORT = process.env.PORT || 7860; // 动态分配的端口23const HOST = '0.0.0.0';24 25// 检查 PORT 是否有效26if (!PORT) {27    console.error("[Error] PORT environment variable is undefined. This is required by Hugging Face Spaces.");28    process.exit(1); // 如果 PORT 未定义,立即退出29}30 31console.log(`Starting server with HOST: ${HOST}, PORT: ${PORT}`);32 33// === 中间件配置 ===34// CORS 配置35const corsOptions = {36    origin: '*', // 允许所有来源的请求37    methods: ['GET', 'POST', 'OPTIONS'],38    allowedHeaders: ['Content-Type'],39};40app.use(cors(corsOptions));41 42// 使用 Body-Parser 解析 JSON 请求体43app.use(bodyParser.json());44 45// 使用 request-ip 中间件获取客户端 IP46app.use(requestIp.mw());47 48// === 内存存储及清理 ===49 50// URL 存储字典(以用户唯一标识符为键)51const urlMap = new Map();52 53// 超时时间配置(以毫秒为单位)54const EXPIRATION_TIME = 5 * 60 * 1000; // 数据保存5分钟55const CLEANUP_INTERVAL = 5.1 * 60 * 1000; // 每 5分6 秒清理一次56 57// 定时清理过期数据58setInterval(() => {59    const now = Date.now();60    const expiredTime = now - EXPIRATION_TIME;61 62    for (const [userId, { timestamp }] of urlMap) {63        if (timestamp < expiredTime) {64            console.log(`Deleting expired data for user: ${userId}`);65            urlMap.delete(userId); // 删除过期数据66        }67    }68}, CLEANUP_INTERVAL);69 70// 健康检查路由71app.get('/', (req, res) => {72    res.status(200).json({73        message: "Server is running with backup port.",74        port: PORT || "undefined",75        environment: process.env,76    });77});78 79// === 辅助函数 ===80// 生成设备指纹81const generateDeviceFingerprint = (req) => {82    const ip = req.clientIp || '';83    const userAgent = req.headers['user-agent'] || '';84    const acceptLanguage = req.headers['accept-language'] || '';85    const connection = req.headers['connection'] || '';86    const encoding = req.headers['accept-encoding'] || '';87    const forwardedFor = req.headers['x-forwarded-for'] || '';88 89    // 将关键信息合并生成唯一指纹90    const rawFingerprint = `${ip}-${userAgent}-${acceptLanguage}-${connection}-${encoding}-${forwardedFor}`;91 92    // 使用 SHA-256 哈希算法生成指纹93    const fingerprint = crypto.createHash('sha256').update(rawFingerprint).digest('hex');94    return fingerprint;95};96 97// === 路由与业务逻辑 ===98 99// 存储 URL(POST 请求)100app.post('/storeURL', (req, res) => {101    const url = req.body.url; // 从请求体中解析 URL102    const ip = req.clientIp; // 获取客户端 IP103 104    // 验证 URL 是否存在并合法105    if (!url) {106        return res.status(400).json({ error: 'URL is required.' });107    }108    try {109        new URL(url); // 验证 URL 格式110    } catch (err) {111        return res.status(400).json({ error: 'Invalid URL format.' });112    }113 114    // 生成用户唯一标识符(包括 IP 和设备指纹)115    const deviceFingerprint = generateDeviceFingerprint(req);116    const userId = `${ip}-${deviceFingerprint}`; // 结合 IP 和设备指纹生成唯一标识符117 118    // 存储到字典中119    urlMap.set(userId, { url, timestamp: Date.now() });120    console.log(`Stored URL for user: ${userId}`);121 122    // 返回成功响应123    res.json({ message: 'URL stored successfully.', userId });124});125 126// 获取 URL(GET 请求)127app.get('/getURL', (req, res) => {128    const ip = req.clientIp; // 获取客户端 IP129 130    // 生成用户唯一标识符(包括 IP 和设备指纹)131    const deviceFingerprint = generateDeviceFingerprint(req);132    const userId = `${ip}-${deviceFingerprint}`;133 134    // 查询字典获取存储的 URL135    if (urlMap.has(userId)) {136        const storedData = urlMap.get(userId);137        storedData.timestamp = Date.now(); // 更新数据时间戳138        urlMap.set(userId, storedData); // 保存更新后的数据139 140        console.log(`Retrieved URL for user: ${userId}`);141        return res.json({ url: storedData.url });142    } else {143        console.error(`No URL found for user: ${userId}`);144        return res.status(404).json({ error: 'URL not found for this user.' });145    }146});147 148// === 启动服务器 ===149app.listen(PORT, HOST, (err) => {150    if (err) {151        console.error("[Error] Server failed to start:", err);152        process.exit(1); // 如果存在错误,立即退出153    }154    console.log(`Server successfully started on http://${HOST}:${PORT}`);155});156 157// 打印环境变量(调试使用)158console.log("Full Environment Variables:", process.env);159