File size: 3,041 Bytes
2889205
e4e9ad6
2889205
e4e9ad6
b0e1d6e
e4e9ad6
2889205
e4e9ad6
 
7f84064
2889205
7f84064
2889205
177a238
2889205
65e323a
 
7f84064
e4e9ad6
 
 
 
 
 
 
 
 
7f84064
315c31e
38265f9
315c31e
65e323a
9a8116c
e4e9ad6
 
315c31e
38265f9
e4e9ad6
 
 
38265f9
65e323a
b0e1d6e
65e323a
e4e9ad6
 
65e323a
 
 
 
e4e9ad6
 
 
65e323a
 
 
315c31e
65e323a
 
315c31e
65e323a
3e0d39c
177a238
65e323a
 
315c31e
3e0d39c
 
e4e9ad6
 
 
 
177a238
65e323a
d5b575b
 
65e323a
315c31e
65e323a
2889205
 
e4e9ad6
 
3e0d39c
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
const express = require('express');
const http = require('http');
const proxy = require('express-http-proxy');
const socketIo = require('socket.io');
const moment = require('moment-timezone');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

const targetUrl = 'https://api.openai.com';
const openaiKey = process.env.OPENAI_KEY;
const port = 7860;
const baseUrl = getExternalUrl(process.env.SPACE_ID);

let requestDetails = []; // Store details of each request
let ipRequestCounts = {}; // Dictionary to keep track of requests per IP

io.on('connection', (socket) => {
    console.log('A user connected to the websocket for live logs.');
});

function logAndEmit(message) {
    console.log(message);  // Continue to log to the console
    io.emit('log', message);  // Emit this log to the frontend via WebSocket
}

app.use('/api', (req, res, next) => {
  if (req.method === 'POST' && req.url.startsWith('/v1/chat/completions')) {
    const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    ipRequestCounts[ip] = (ipRequestCounts[ip] || 0) + 1;

    if (ipRequestCounts[ip] > 20 ) {
      const rateLimitMessage = `IP ${ip} hit rate limit with ${ipRequestCounts[ip]} requests.`;
      logAndEmit(rateLimitMessage);
      return res.status(429).send('You have reached the 10 message limit. Please contact support for more information.');
    }
    
    const logMessage = `IP ${ip} has made ${ipRequestCounts[ip]} requests so far.`;
    logAndEmit(logMessage);
  }

  const timestamp = moment().tz("Asia/Tbilisi").format();
  const requestData = {
    requestNumber: ipRequestCounts[req.headers['x-forwarded-for'] || req.connection.remoteAddress],
    ip: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
    timestamp: timestamp,
    text: req.method + ' ' + req.url
  };
  requestDetails.push(requestData);
  
  const detailedLog = `Request ${requestData.requestNumber} on ${requestData.timestamp} from IP ${requestData.ip} with method "${req.method}" and text "${requestData.text}"`;
  logAndEmit(detailedLog);

  next();
}, proxy(targetUrl, {
  proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
    proxyReqOpts.headers['Authorization'] = 'Bearer ' + openaiKey;
    return proxyReqOpts;
  }
}));

app.get("/", (req, res) => {
  let requestsInfo = requestDetails.map(detail =>
    `Request ${detail.requestNumber} on ${detail.timestamp} from IP ${detail.ip} with text "${detail.text}"`).join('<br>');
  res.send(`This is your OpenAI Reverse Proxy URL: ${baseUrl}.<br><br>Requests Overview:<br>${requestsInfo}`);
});

app.get('/logs', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

function getExternalUrl(spaceId) {
  try {
    const [username, spacename] = spaceId.split("/");
    return `https://${username}-${spacename.replace(/_/g, "-")}.hf.space/api/v1`;
  } catch (e) {
    return "Error generating external URL";
  }
}

server.listen(port, () => {
   logAndEmit(`Reverse proxy server and WebSocket running on port ${port}`);
});