feat: sync deployed v1.0.0-rc.38-custom.42

Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
cneicy committed 2026-09-26 04:49:11 +08:00
1 parent aa6c3f50f4
commit ceddfd3d6b
828 files changed
+122253 -13702

No files matched your search

+45 -19
View File
@@ -361,20 +361,7 @@ func TokenAuthReadOnly() func(c *gin.Context) {
func TokenAuth() func(c *gin.Context) {
return func(c *gin.Context) {
// 先检测是否为ws
if c.Request.Header.Get("Sec-WebSocket-Protocol") != "" {
// Sec-WebSocket-Protocol: realtime, openai-insecure-api-key.sk-xxx, openai-beta.realtime-v1
// read sk from Sec-WebSocket-Protocol
key := c.Request.Header.Get("Sec-WebSocket-Protocol")
parts := strings.SplitSeq(key, ",")
for part := range parts {
part = strings.TrimSpace(part)
if strings.HasPrefix(part, "openai-insecure-api-key") {
key = strings.TrimPrefix(part, "openai-insecure-api-key.")
break
}
}
c.Request.Header.Set("Authorization", "Bearer "+key)
}
applyWebSocketSubprotocolAuthorization(c.Request.Header)
// 检查path包含/v1/messages 或 /v1/models
if strings.Contains(c.Request.URL.Path, "/v1/messages") || strings.Contains(c.Request.URL.Path, "/v1/models") {
anthropicKey := c.Request.Header.Get("x-api-key")
@@ -467,7 +454,7 @@ func TokenAuth() func(c *gin.Context) {
userGroup := userCache.Group
tokenGroup := token.Group
if tokenGroup != "" {
if tokenGroup != "" && token.RoutingPolicy == "" {
// check common.UserUsableGroups[userGroup]
if _, ok := service.GetUserUsableGroups(userGroup)[tokenGroup]; !ok {
abortWithOpenAiMessage(c, http.StatusForbidden, fmt.Sprintf("无权访问 %s 分组", tokenGroup))
@@ -486,12 +473,39 @@ func TokenAuth() func(c *gin.Context) {
err = SetupContextForToken(c, token, parts...)
if err != nil {
if !c.IsAborted() {
abortWithOpenAiMessage(c, http.StatusForbidden, "Invalid token routing policy")
}
return
}
c.Next()
}
}
func applyWebSocketSubprotocolAuthorization(header http.Header) bool {
key, ok := apiKeyFromWebSocketSubprotocol(strings.Join(header.Values("Sec-WebSocket-Protocol"), ","))
if !ok {
return false
}
header.Set("Authorization", "Bearer "+key)
return true
}
func apiKeyFromWebSocketSubprotocol(protocols string) (string, bool) {
if protocols == "" {
return "", false
}
const insecureAPIKeyPrefix = "openai-insecure-api-key."
for part := range strings.SplitSeq(protocols, ",") {
part = strings.TrimSpace(part)
if strings.HasPrefix(part, insecureAPIKeyPrefix) {
key := strings.TrimPrefix(part, insecureAPIKeyPrefix)
return key, key != ""
}
}
return "", false
}
func SetupContextForToken(c *gin.Context, token *model.Token, parts ...string) error {
if token == nil {
return fmt.Errorf("token is nil")
@@ -511,15 +525,27 @@ func SetupContextForToken(c *gin.Context, token *model.Token, parts ...string) e
c.Set("token_model_limit_enabled", false)
}
common.SetContextKey(c, constant.ContextKeyTokenGroup, token.Group)
common.SetContextKey(c, constant.ContextKeyTokenAstraAutoSwitch, token.AstraAutoSwitch && token.AstraDetectionEnabled)
common.SetContextKey(c, constant.ContextKeyTokenAstraDetectionDisabled, !token.AstraDetectionEnabled)
common.SetContextKey(c, constant.ContextKeyTokenCrossGroupRetry, token.CrossGroupRetry)
if policy, err := token.GetRoutingPolicy(); err != nil {
return err
} else if policy != nil {
c.Set(model.TokenRoutingContextKey, policy)
common.SetContextKey(c, constant.ContextKeyTokenCrossGroupRetry, true)
}
if token.AutoGroups != "" {
autoGroups, err := token.GetAutoGroups()
groupPool, err := token.GetGroupPool()
if err != nil {
common.SysError(fmt.Sprintf("failed to parse auto groups for token %d: %v", token.Id, err))
autoGroups = []string{}
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, autoGroups)
} else if len(autoGroups) > 0 {
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, []string{})
} else if len(groupPool) > 0 {
autoGroups := make([]string, 0, len(groupPool))
for _, entry := range groupPool {
autoGroups = append(autoGroups, entry.Group)
}
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, autoGroups)
common.SetContextKey(c, constant.ContextKeyTokenGroupPool, groupPool)
}
}
if len(parts) > 1 {