GeminiBot commited on
Commit
4bca23b
·
1 Parent(s): 7bfd1f6

Port server from Bun to Node.js http module

Browse files
Files changed (1) hide show
  1. src/server.ts +81 -47
src/server.ts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { OpenAIService } from "./openai-service";
2
 
3
  const openAIService = new OpenAIService();
@@ -33,54 +34,87 @@ const HTML_FRONTEND = `
33
  </html>
34
  `;
35
 
36
- try {
37
- const server = Bun.serve({
38
- port: process.env.PORT || 7860,
39
- async fetch(req) {
40
- const url = new URL(req.url);
41
-
42
- // Маскировочный фронтенд
43
- if (url.pathname === "/") {
44
- return new Response(HTML_FRONTEND, { headers: { "Content-Type": "text/html" } });
45
- }
46
-
47
- const authHeader = req.headers.get("Authorization");
48
- const API_KEY = process.env.API_KEY || "MySecretKey_12345";
49
-
50
- if (authHeader !== `Bearer ${API_KEY}` && req.method !== "OPTIONS") {
51
- return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
52
- }
53
-
54
- const corsHeaders = {
55
- "Access-Control-Allow-Origin": "*",
56
- "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
57
- "Access-Control-Allow-Headers": "Content-Type, Authorization",
58
- };
59
-
60
- if (req.method === "OPTIONS") return new Response(null, { headers: corsHeaders });
61
-
62
- try {
63
- if (url.pathname === "/health") {
64
- return new Response(JSON.stringify({ status: "online", model: "distributed-v1" }), { headers: { "Content-Type": "application/json", ...corsHeaders } });
65
- }
 
66
 
67
- if (url.pathname === "/v1/chat/completions" && req.method === "POST") {
68
- const body = await req.json();
69
- const lastMsg = body.messages?.[body.messages.length - 1]?.content || "";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  log(`REQ: ${lastMsg.substring(0, 50)}...`);
71
- const completion = await openAIService.createChatCompletion(body);
72
- return new Response(JSON.stringify(completion), { headers: { "Content-Type": "application/json", ...corsHeaders } });
 
 
 
 
73
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- return new Response(null, { status: 404 });
76
- } catch (error) {
77
- log(`ERR: ${error.message}`);
78
- return new Response(JSON.stringify({ error: error.message }), { status: 500, headers: corsHeaders });
79
- }
80
- },
81
- });
82
-
83
- log(`API Gateway started on port ${server.port}`);
84
- } catch (error) {
85
- process.exit(1);
86
- }
 
1
+ import { createServer, IncomingMessage, ServerResponse } from "node:http";
2
  import { OpenAIService } from "./openai-service";
3
 
4
  const openAIService = new OpenAIService();
 
34
  </html>
35
  `;
36
 
37
+ const API_KEY = process.env.API_KEY || "MySecretKey_12345";
38
+ const PORT = Number(process.env.PORT) || 7860;
39
+
40
+ const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {
41
+ try {
42
+ const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
43
+ const method = req.method;
44
+
45
+ // CORS Headers
46
+ const corsHeaders = {
47
+ "Access-Control-Allow-Origin": "*",
48
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
49
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
50
+ };
51
+
52
+ // Helper to send JSON response
53
+ const sendJSON = (statusCode: number, data: any) => {
54
+ res.writeHead(statusCode, { "Content-Type": "application/json", ...corsHeaders });
55
+ res.end(JSON.stringify(data));
56
+ };
57
+
58
+ // Helper to send HTML
59
+ const sendHTML = (html: string) => {
60
+ res.writeHead(200, { "Content-Type": "text/html", ...corsHeaders });
61
+ res.end(html);
62
+ };
63
+
64
+ // Masking Frontend
65
+ if (url.pathname === "/" && method === "GET") {
66
+ return sendHTML(HTML_FRONTEND);
67
+ }
68
 
69
+ // Handle Preflight
70
+ if (method === "OPTIONS") {
71
+ res.writeHead(204, corsHeaders);
72
+ res.end();
73
+ return;
74
+ }
75
+
76
+ // Auth Check
77
+ const authHeader = req.headers["authorization"];
78
+ if (url.pathname.startsWith("/v1/") && authHeader !== `Bearer ${API_KEY}`) {
79
+ return sendJSON(401, { error: "Unauthorized" });
80
+ }
81
+
82
+ // Health Check
83
+ if (url.pathname === "/health") {
84
+ return sendJSON(200, { status: "online", model: "distributed-v1" });
85
+ }
86
+
87
+ // Chat Completions
88
+ if (url.pathname === "/v1/chat/completions" && method === "POST") {
89
+ let body = "";
90
+ req.on("data", (chunk) => { body += chunk; });
91
+ req.on("end", async () => {
92
+ try {
93
+ const jsonBody = JSON.parse(body);
94
+ const lastMsg = jsonBody.messages?.[jsonBody.messages.length - 1]?.content || "";
95
  log(`REQ: ${lastMsg.substring(0, 50)}...`);
96
+
97
+ const completion = await openAIService.createChatCompletion(jsonBody);
98
+ sendJSON(200, completion);
99
+ } catch (error: any) {
100
+ log(`ERR: ${error.message}`);
101
+ sendJSON(500, { error: error.message });
102
  }
103
+ });
104
+ return;
105
+ }
106
+
107
+ // Not Found
108
+ res.writeHead(404, corsHeaders);
109
+ res.end();
110
+
111
+ } catch (error: any) {
112
+ log(`CRITICAL ERR: ${error.message}`);
113
+ res.writeHead(500, { "Content-Type": "application/json" });
114
+ res.end(JSON.stringify({ error: "Internal Server Error" }));
115
+ }
116
+ });
117
 
118
+ server.listen(PORT, () => {
119
+ log(`API Gateway started on port ${PORT}`);
120
+ });