zai2api3 / cmd /main.go
bg5's picture
部署 zai2api3 到 HF Space
ac613eb verified
Raw History Blame Contribute Delete
5.29 kB
package main
import (
"encoding/json"
"net/http"
"time"
"zai-proxy/internal"
)
func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Credentials", "true")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next(w, r)
}
}
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
// 获取客户端 IP
clientIP := internal.GetClientIP(r)
next(wrapped, r)
duration := time.Since(start)
internal.LogInfo("%s %s %d %v [%s]", r.Method, r.URL.Path, wrapped.statusCode, duration, clientIP)
}
}
type responseWriter struct {
http.ResponseWriter
statusCode int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
func (rw *responseWriter) Flush() {
if flusher, ok := rw.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
}
}
func handleRoot(w http.ResponseWriter, r *http.Request) {
telemetry := internal.GetTelemetryData()
response := map[string]interface{}{
"message": "Chat-Glm API",
"version": "2.0.0",
"telemetry": map[string]interface{}{
"uptime": telemetry.Uptime,
"total_requests": telemetry.TotalRequests,
"rpm": telemetry.RPM,
"total_input_tokens": telemetry.TotalInputTok,
"total_output_tokens": telemetry.TotalOutputTok,
"avg_input_tokens": telemetry.AvgInputTok,
"avg_output_tokens": telemetry.AvgOutputTok,
"valid_tokens": telemetry.ValidTokens,
"multimodal_calls": telemetry.MultimodalCalls,
"total_calls": telemetry.TotalCalls,
"success_calls": telemetry.SuccessCalls,
"success_rate": telemetry.SuccessRate,
"model_stats": telemetry.ModelStats,
},
}
if len(internal.Cfg.Note) > 0 {
response["note"] = internal.Cfg.Note
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func main() {
internal.LoadConfig()
internal.InitLogger()
if err := internal.GetTokenManager().Start(); err != nil {
internal.LogError("TokenManager 启动失败: %v", err)
}
internal.StartAnonymousTokenPool()
internal.StartVersionUpdater()
internal.StartModelFetcher()
internal.GetApiKeyManager().StartPeriodicSave()
http.HandleFunc("/", corsMiddleware(loggingMiddleware(handleRoot)))
http.HandleFunc("/v1/models", corsMiddleware(loggingMiddleware(internal.HandleModels)))
http.HandleFunc("/v1/chat/completions", corsMiddleware(loggingMiddleware(internal.HandleChatCompletions)))
// Admin Web UI
http.HandleFunc("/admin", corsMiddleware(loggingMiddleware(internal.HandleAdminUI)))
http.HandleFunc("/admin/", corsMiddleware(loggingMiddleware(internal.HandleAdminUI)))
http.HandleFunc("/admin/api/login", corsMiddleware(loggingMiddleware(internal.HandleAdminLogin)))
http.HandleFunc("/admin/api/logout", corsMiddleware(loggingMiddleware(internal.HandleAdminLogout)))
http.HandleFunc("/admin/api/overview", corsMiddleware(loggingMiddleware(internal.HandleAdminOverview)))
http.HandleFunc("/admin/api/config", corsMiddleware(loggingMiddleware(internal.HandleAdminConfig)))
// Tokens:GET 列表 / POST 添加 / DELETE 删除 / POST validate 验证
http.HandleFunc("/admin/api/tokens", corsMiddleware(loggingMiddleware(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
internal.HandleAdminTokens(w, r)
case http.MethodPost:
internal.HandleAdminTokenAdd(w, r)
case http.MethodDelete:
internal.HandleAdminTokenDelete(w, r)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
})))
http.HandleFunc("/admin/api/tokens/validate", corsMiddleware(loggingMiddleware(internal.HandleAdminTokenValidate)))
// API Keys
http.HandleFunc("/admin/api/keys", corsMiddleware(loggingMiddleware(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
internal.HandleAdminKeysList(w, r)
case http.MethodPost:
internal.HandleAdminKeysCreate(w, r)
case http.MethodDelete:
internal.HandleAdminKeysDelete(w, r)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
})))
http.HandleFunc("/admin/api/keys/toggle", corsMiddleware(loggingMiddleware(internal.HandleAdminKeysToggle)))
http.HandleFunc("/admin/api/models", corsMiddleware(loggingMiddleware(internal.HandleAdminModels)))
http.HandleFunc("/admin/api/test", corsMiddleware(loggingMiddleware(internal.HandleAdminTestModel)))
addr := ":" + internal.Cfg.Port
internal.LogInfo("Server starting on %s", addr)
internal.LogInfo("API docs available at http://localhost:%s/v1/models", internal.Cfg.Port)
if err := http.ListenAndServe(addr, nil); err != nil {
internal.LogError("Server failed: %v", err)
}
}