Files
opencatd-open/router/router.go
2025-01-01 23:10:01 +08:00

104 lines
2.1 KiB
Go

package router
import (
"crypto/tls"
"net"
"net/http"
"net/http/httputil"
"opencatd-open/pkg/claude"
oai "opencatd-open/pkg/openai"
"opencatd-open/store"
"time"
"github.com/gin-gonic/gin"
)
func HandleProxy(c *gin.Context) {
var (
localuser bool
)
auth := c.Request.Header.Get("Authorization")
if len(auth) > 7 && auth[:7] == "Bearer " {
localuser = store.IsExistAuthCache(auth[7:])
c.Set("localuser", auth[7:])
}
if c.Request.URL.Path == "/v1/complete" {
if localuser {
claude.ClaudeProxy(c)
return
} else {
HandleReverseProxy(c, "api.anthropic.com")
return
}
}
if c.Request.URL.Path == "/v1/audio/transcriptions" {
oai.WhisperProxy(c)
return
}
if c.Request.URL.Path == "/v1/audio/speech" {
oai.SpeechProxy(c)
return
}
if c.Request.URL.Path == "/v1/images/generations" {
oai.DallEProxy(c)
return
}
if c.Request.URL.Path == "/v1/realtime" {
oai.RealTimeProxy(c)
return
}
if c.Request.URL.Path == "/v1/chat/completions" {
if localuser {
if store.KeysCache.ItemCount() == 0 {
c.JSON(http.StatusBadGateway, gin.H{"error": gin.H{
"message": "No Api-Key Available",
}})
return
}
ChatHandler(c)
return
}
} else {
HandleReverseProxy(c, "api.openai.com")
return
}
}
func HandleReverseProxy(c *gin.Context, targetHost string) {
proxy := &httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = "https"
req.URL.Host = targetHost
},
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
req, err := http.NewRequest(c.Request.Method, c.Request.URL.Path, c.Request.Body)
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
return
}
req.Header = c.Request.Header
proxy.ServeHTTP(c.Writer, req)
return
}