Merge pull request #227 from router-for-me/api
add headers support for api
This commit is contained in:
@@ -148,7 +148,7 @@ func (h *Handler) applyLegacyKeys(keys []string) {
|
|||||||
}
|
}
|
||||||
h.cfg.GeminiKey = newList
|
h.cfg.GeminiKey = newList
|
||||||
h.cfg.GlAPIKey = sanitized
|
h.cfg.GlAPIKey = sanitized
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
// api-keys
|
// api-keys
|
||||||
@@ -206,7 +206,7 @@ func (h *Handler) PutGeminiKeys(c *gin.Context) {
|
|||||||
arr = obj.Items
|
arr = obj.Items
|
||||||
}
|
}
|
||||||
h.cfg.GeminiKey = append([]config.GeminiKey(nil), arr...)
|
h.cfg.GeminiKey = append([]config.GeminiKey(nil), arr...)
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
}
|
}
|
||||||
func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
||||||
@@ -227,7 +227,7 @@ func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
|||||||
// Treat empty API key as delete.
|
// Treat empty API key as delete.
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.GeminiKey) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.GeminiKey) {
|
||||||
h.cfg.GeminiKey = append(h.cfg.GeminiKey[:*body.Index], h.cfg.GeminiKey[*body.Index+1:]...)
|
h.cfg.GeminiKey = append(h.cfg.GeminiKey[:*body.Index], h.cfg.GeminiKey[*body.Index+1:]...)
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -245,7 +245,7 @@ func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if removed {
|
if removed {
|
||||||
h.cfg.GeminiKey = out
|
h.cfg.GeminiKey = out
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
|||||||
|
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.GeminiKey) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.GeminiKey) {
|
||||||
h.cfg.GeminiKey[*body.Index] = value
|
h.cfg.GeminiKey[*body.Index] = value
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -266,7 +266,7 @@ func (h *Handler) PatchGeminiKey(c *gin.Context) {
|
|||||||
for i := range h.cfg.GeminiKey {
|
for i := range h.cfg.GeminiKey {
|
||||||
if h.cfg.GeminiKey[i].APIKey == match {
|
if h.cfg.GeminiKey[i].APIKey == match {
|
||||||
h.cfg.GeminiKey[i] = value
|
h.cfg.GeminiKey[i] = value
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ func (h *Handler) DeleteGeminiKey(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if len(out) != len(h.cfg.GeminiKey) {
|
if len(out) != len(h.cfg.GeminiKey) {
|
||||||
h.cfg.GeminiKey = out
|
h.cfg.GeminiKey = out
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
} else {
|
} else {
|
||||||
c.JSON(404, gin.H{"error": "item not found"})
|
c.JSON(404, gin.H{"error": "item not found"})
|
||||||
@@ -295,7 +295,7 @@ func (h *Handler) DeleteGeminiKey(c *gin.Context) {
|
|||||||
var idx int
|
var idx int
|
||||||
if _, err := fmt.Sscanf(idxStr, "%d", &idx); err == nil && idx >= 0 && idx < len(h.cfg.GeminiKey) {
|
if _, err := fmt.Sscanf(idxStr, "%d", &idx); err == nil && idx >= 0 && idx < len(h.cfg.GeminiKey) {
|
||||||
h.cfg.GeminiKey = append(h.cfg.GeminiKey[:idx], h.cfg.GeminiKey[idx+1:]...)
|
h.cfg.GeminiKey = append(h.cfg.GeminiKey[:idx], h.cfg.GeminiKey[idx+1:]...)
|
||||||
h.cfg.SyncGeminiKeys()
|
h.cfg.SanitizeGeminiKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -328,6 +328,7 @@ func (h *Handler) PutClaudeKeys(c *gin.Context) {
|
|||||||
normalizeClaudeKey(&arr[i])
|
normalizeClaudeKey(&arr[i])
|
||||||
}
|
}
|
||||||
h.cfg.ClaudeKey = arr
|
h.cfg.ClaudeKey = arr
|
||||||
|
h.cfg.SanitizeClaudeKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
}
|
}
|
||||||
func (h *Handler) PatchClaudeKey(c *gin.Context) {
|
func (h *Handler) PatchClaudeKey(c *gin.Context) {
|
||||||
@@ -340,16 +341,19 @@ func (h *Handler) PatchClaudeKey(c *gin.Context) {
|
|||||||
c.JSON(400, gin.H{"error": "invalid body"})
|
c.JSON(400, gin.H{"error": "invalid body"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
normalizeClaudeKey(body.Value)
|
value := *body.Value
|
||||||
|
normalizeClaudeKey(&value)
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.ClaudeKey) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.ClaudeKey) {
|
||||||
h.cfg.ClaudeKey[*body.Index] = *body.Value
|
h.cfg.ClaudeKey[*body.Index] = value
|
||||||
|
h.cfg.SanitizeClaudeKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if body.Match != nil {
|
if body.Match != nil {
|
||||||
for i := range h.cfg.ClaudeKey {
|
for i := range h.cfg.ClaudeKey {
|
||||||
if h.cfg.ClaudeKey[i].APIKey == *body.Match {
|
if h.cfg.ClaudeKey[i].APIKey == *body.Match {
|
||||||
h.cfg.ClaudeKey[i] = *body.Value
|
h.cfg.ClaudeKey[i] = value
|
||||||
|
h.cfg.SanitizeClaudeKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -366,6 +370,7 @@ func (h *Handler) DeleteClaudeKey(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.cfg.ClaudeKey = out
|
h.cfg.ClaudeKey = out
|
||||||
|
h.cfg.SanitizeClaudeKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -374,6 +379,7 @@ func (h *Handler) DeleteClaudeKey(c *gin.Context) {
|
|||||||
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
||||||
if err == nil && idx >= 0 && idx < len(h.cfg.ClaudeKey) {
|
if err == nil && idx >= 0 && idx < len(h.cfg.ClaudeKey) {
|
||||||
h.cfg.ClaudeKey = append(h.cfg.ClaudeKey[:idx], h.cfg.ClaudeKey[idx+1:]...)
|
h.cfg.ClaudeKey = append(h.cfg.ClaudeKey[:idx], h.cfg.ClaudeKey[idx+1:]...)
|
||||||
|
h.cfg.SanitizeClaudeKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -413,6 +419,7 @@ func (h *Handler) PutOpenAICompat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.cfg.OpenAICompatibility = filtered
|
h.cfg.OpenAICompatibility = filtered
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
}
|
}
|
||||||
func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
||||||
@@ -430,6 +437,7 @@ func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
|||||||
if strings.TrimSpace(body.Value.BaseURL) == "" {
|
if strings.TrimSpace(body.Value.BaseURL) == "" {
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.OpenAICompatibility) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.OpenAICompatibility) {
|
||||||
h.cfg.OpenAICompatibility = append(h.cfg.OpenAICompatibility[:*body.Index], h.cfg.OpenAICompatibility[*body.Index+1:]...)
|
h.cfg.OpenAICompatibility = append(h.cfg.OpenAICompatibility[:*body.Index], h.cfg.OpenAICompatibility[*body.Index+1:]...)
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -445,6 +453,7 @@ func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if removed {
|
if removed {
|
||||||
h.cfg.OpenAICompatibility = out
|
h.cfg.OpenAICompatibility = out
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -454,6 +463,7 @@ func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.OpenAICompatibility) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.OpenAICompatibility) {
|
||||||
h.cfg.OpenAICompatibility[*body.Index] = *body.Value
|
h.cfg.OpenAICompatibility[*body.Index] = *body.Value
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -461,6 +471,7 @@ func (h *Handler) PatchOpenAICompat(c *gin.Context) {
|
|||||||
for i := range h.cfg.OpenAICompatibility {
|
for i := range h.cfg.OpenAICompatibility {
|
||||||
if h.cfg.OpenAICompatibility[i].Name == *body.Name {
|
if h.cfg.OpenAICompatibility[i].Name == *body.Name {
|
||||||
h.cfg.OpenAICompatibility[i] = *body.Value
|
h.cfg.OpenAICompatibility[i] = *body.Value
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -477,6 +488,7 @@ func (h *Handler) DeleteOpenAICompat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.cfg.OpenAICompatibility = out
|
h.cfg.OpenAICompatibility = out
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -485,6 +497,7 @@ func (h *Handler) DeleteOpenAICompat(c *gin.Context) {
|
|||||||
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
||||||
if err == nil && idx >= 0 && idx < len(h.cfg.OpenAICompatibility) {
|
if err == nil && idx >= 0 && idx < len(h.cfg.OpenAICompatibility) {
|
||||||
h.cfg.OpenAICompatibility = append(h.cfg.OpenAICompatibility[:idx], h.cfg.OpenAICompatibility[idx+1:]...)
|
h.cfg.OpenAICompatibility = append(h.cfg.OpenAICompatibility[:idx], h.cfg.OpenAICompatibility[idx+1:]...)
|
||||||
|
h.cfg.SanitizeOpenAICompatibility()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -517,13 +530,17 @@ func (h *Handler) PutCodexKeys(c *gin.Context) {
|
|||||||
filtered := make([]config.CodexKey, 0, len(arr))
|
filtered := make([]config.CodexKey, 0, len(arr))
|
||||||
for i := range arr {
|
for i := range arr {
|
||||||
entry := arr[i]
|
entry := arr[i]
|
||||||
|
entry.APIKey = strings.TrimSpace(entry.APIKey)
|
||||||
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
||||||
|
entry.ProxyURL = strings.TrimSpace(entry.ProxyURL)
|
||||||
|
entry.Headers = config.NormalizeHeaders(entry.Headers)
|
||||||
if entry.BaseURL == "" {
|
if entry.BaseURL == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filtered = append(filtered, entry)
|
filtered = append(filtered, entry)
|
||||||
}
|
}
|
||||||
h.cfg.CodexKey = filtered
|
h.cfg.CodexKey = filtered
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
}
|
}
|
||||||
func (h *Handler) PatchCodexKey(c *gin.Context) {
|
func (h *Handler) PatchCodexKey(c *gin.Context) {
|
||||||
@@ -536,10 +553,16 @@ func (h *Handler) PatchCodexKey(c *gin.Context) {
|
|||||||
c.JSON(400, gin.H{"error": "invalid body"})
|
c.JSON(400, gin.H{"error": "invalid body"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
value := *body.Value
|
||||||
|
value.APIKey = strings.TrimSpace(value.APIKey)
|
||||||
|
value.BaseURL = strings.TrimSpace(value.BaseURL)
|
||||||
|
value.ProxyURL = strings.TrimSpace(value.ProxyURL)
|
||||||
|
value.Headers = config.NormalizeHeaders(value.Headers)
|
||||||
// If base-url becomes empty, delete instead of update
|
// If base-url becomes empty, delete instead of update
|
||||||
if strings.TrimSpace(body.Value.BaseURL) == "" {
|
if value.BaseURL == "" {
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.CodexKey) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.CodexKey) {
|
||||||
h.cfg.CodexKey = append(h.cfg.CodexKey[:*body.Index], h.cfg.CodexKey[*body.Index+1:]...)
|
h.cfg.CodexKey = append(h.cfg.CodexKey[:*body.Index], h.cfg.CodexKey[*body.Index+1:]...)
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -555,20 +578,23 @@ func (h *Handler) PatchCodexKey(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if removed {
|
if removed {
|
||||||
h.cfg.CodexKey = out
|
h.cfg.CodexKey = out
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.CodexKey) {
|
if body.Index != nil && *body.Index >= 0 && *body.Index < len(h.cfg.CodexKey) {
|
||||||
h.cfg.CodexKey[*body.Index] = *body.Value
|
h.cfg.CodexKey[*body.Index] = value
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if body.Match != nil {
|
if body.Match != nil {
|
||||||
for i := range h.cfg.CodexKey {
|
for i := range h.cfg.CodexKey {
|
||||||
if h.cfg.CodexKey[i].APIKey == *body.Match {
|
if h.cfg.CodexKey[i].APIKey == *body.Match {
|
||||||
h.cfg.CodexKey[i] = *body.Value
|
h.cfg.CodexKey[i] = value
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -586,6 +612,7 @@ func (h *Handler) DeleteCodexKey(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.cfg.CodexKey = out
|
h.cfg.CodexKey = out
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -594,6 +621,7 @@ func (h *Handler) DeleteCodexKey(c *gin.Context) {
|
|||||||
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
_, err := fmt.Sscanf(idxStr, "%d", &idx)
|
||||||
if err == nil && idx >= 0 && idx < len(h.cfg.CodexKey) {
|
if err == nil && idx >= 0 && idx < len(h.cfg.CodexKey) {
|
||||||
h.cfg.CodexKey = append(h.cfg.CodexKey[:idx], h.cfg.CodexKey[idx+1:]...)
|
h.cfg.CodexKey = append(h.cfg.CodexKey[:idx], h.cfg.CodexKey[idx+1:]...)
|
||||||
|
h.cfg.SanitizeCodexKeys()
|
||||||
h.persist(c)
|
h.persist(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -607,6 +635,7 @@ func normalizeOpenAICompatibilityEntry(entry *config.OpenAICompatibility) {
|
|||||||
}
|
}
|
||||||
// Trim base-url; empty base-url indicates provider should be removed by sanitization
|
// Trim base-url; empty base-url indicates provider should be removed by sanitization
|
||||||
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
||||||
|
entry.Headers = config.NormalizeHeaders(entry.Headers)
|
||||||
existing := make(map[string]struct{}, len(entry.APIKeyEntries))
|
existing := make(map[string]struct{}, len(entry.APIKeyEntries))
|
||||||
for i := range entry.APIKeyEntries {
|
for i := range entry.APIKeyEntries {
|
||||||
trimmed := strings.TrimSpace(entry.APIKeyEntries[i].APIKey)
|
trimmed := strings.TrimSpace(entry.APIKeyEntries[i].APIKey)
|
||||||
@@ -658,6 +687,7 @@ func normalizeClaudeKey(entry *config.ClaudeKey) {
|
|||||||
entry.APIKey = strings.TrimSpace(entry.APIKey)
|
entry.APIKey = strings.TrimSpace(entry.APIKey)
|
||||||
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
||||||
entry.ProxyURL = strings.TrimSpace(entry.ProxyURL)
|
entry.ProxyURL = strings.TrimSpace(entry.ProxyURL)
|
||||||
|
entry.Headers = config.NormalizeHeaders(entry.Headers)
|
||||||
if len(entry.Models) == 0 {
|
if len(entry.Models) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-19
@@ -255,26 +255,26 @@ func LoadConfigOptional(configFile string, optional bool) (*Config, error) {
|
|||||||
// Sync request authentication providers with inline API keys for backwards compatibility.
|
// Sync request authentication providers with inline API keys for backwards compatibility.
|
||||||
syncInlineAccessProvider(&cfg)
|
syncInlineAccessProvider(&cfg)
|
||||||
|
|
||||||
// Normalize Gemini API key configuration and migrate legacy entries.
|
// Sanitize Gemini API key configuration and migrate legacy entries.
|
||||||
cfg.SyncGeminiKeys()
|
cfg.SanitizeGeminiKeys()
|
||||||
|
|
||||||
// Sanitize OpenAI compatibility providers: drop entries without base-url
|
|
||||||
sanitizeOpenAICompatibility(&cfg)
|
|
||||||
|
|
||||||
// Sanitize Codex keys: drop entries without base-url
|
// Sanitize Codex keys: drop entries without base-url
|
||||||
sanitizeCodexKeys(&cfg)
|
cfg.SanitizeCodexKeys()
|
||||||
|
|
||||||
// Normalize Claude key headers
|
// Sanitize Claude key headers
|
||||||
normalizeClaudeKeys(&cfg)
|
cfg.SanitizeClaudeKeys()
|
||||||
|
|
||||||
|
// Sanitize OpenAI compatibility providers: drop entries without base-url
|
||||||
|
cfg.SanitizeOpenAICompatibility()
|
||||||
|
|
||||||
// Return the populated configuration struct.
|
// Return the populated configuration struct.
|
||||||
return &cfg, nil
|
return &cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitizeOpenAICompatibility removes OpenAI-compatibility provider entries that are
|
// SanitizeOpenAICompatibility removes OpenAI-compatibility provider entries that are
|
||||||
// not actionable, specifically those missing a BaseURL. It trims whitespace before
|
// not actionable, specifically those missing a BaseURL. It trims whitespace before
|
||||||
// evaluation and preserves the relative order of remaining entries.
|
// evaluation and preserves the relative order of remaining entries.
|
||||||
func sanitizeOpenAICompatibility(cfg *Config) {
|
func (cfg *Config) SanitizeOpenAICompatibility() {
|
||||||
if cfg == nil || len(cfg.OpenAICompatibility) == 0 {
|
if cfg == nil || len(cfg.OpenAICompatibility) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ func sanitizeOpenAICompatibility(cfg *Config) {
|
|||||||
e := cfg.OpenAICompatibility[i]
|
e := cfg.OpenAICompatibility[i]
|
||||||
e.Name = strings.TrimSpace(e.Name)
|
e.Name = strings.TrimSpace(e.Name)
|
||||||
e.BaseURL = strings.TrimSpace(e.BaseURL)
|
e.BaseURL = strings.TrimSpace(e.BaseURL)
|
||||||
e.Headers = normalizeHeaders(e.Headers)
|
e.Headers = NormalizeHeaders(e.Headers)
|
||||||
if e.BaseURL == "" {
|
if e.BaseURL == "" {
|
||||||
// Skip providers with no base-url; treated as removed
|
// Skip providers with no base-url; treated as removed
|
||||||
continue
|
continue
|
||||||
@@ -293,9 +293,9 @@ func sanitizeOpenAICompatibility(cfg *Config) {
|
|||||||
cfg.OpenAICompatibility = out
|
cfg.OpenAICompatibility = out
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitizeCodexKeys removes Codex API key entries missing a BaseURL.
|
// SanitizeCodexKeys removes Codex API key entries missing a BaseURL.
|
||||||
// It trims whitespace and preserves order for remaining entries.
|
// It trims whitespace and preserves order for remaining entries.
|
||||||
func sanitizeCodexKeys(cfg *Config) {
|
func (cfg *Config) SanitizeCodexKeys() {
|
||||||
if cfg == nil || len(cfg.CodexKey) == 0 {
|
if cfg == nil || len(cfg.CodexKey) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ func sanitizeCodexKeys(cfg *Config) {
|
|||||||
for i := range cfg.CodexKey {
|
for i := range cfg.CodexKey {
|
||||||
e := cfg.CodexKey[i]
|
e := cfg.CodexKey[i]
|
||||||
e.BaseURL = strings.TrimSpace(e.BaseURL)
|
e.BaseURL = strings.TrimSpace(e.BaseURL)
|
||||||
e.Headers = normalizeHeaders(e.Headers)
|
e.Headers = NormalizeHeaders(e.Headers)
|
||||||
if e.BaseURL == "" {
|
if e.BaseURL == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -312,17 +312,19 @@ func sanitizeCodexKeys(cfg *Config) {
|
|||||||
cfg.CodexKey = out
|
cfg.CodexKey = out
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeClaudeKeys(cfg *Config) {
|
// SanitizeClaudeKeys normalizes headers for Claude credentials.
|
||||||
|
func (cfg *Config) SanitizeClaudeKeys() {
|
||||||
if cfg == nil || len(cfg.ClaudeKey) == 0 {
|
if cfg == nil || len(cfg.ClaudeKey) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := range cfg.ClaudeKey {
|
for i := range cfg.ClaudeKey {
|
||||||
entry := &cfg.ClaudeKey[i]
|
entry := &cfg.ClaudeKey[i]
|
||||||
entry.Headers = normalizeHeaders(entry.Headers)
|
entry.Headers = NormalizeHeaders(entry.Headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) SyncGeminiKeys() {
|
// SanitizeGeminiKeys deduplicates and normalizes Gemini credentials.
|
||||||
|
func (cfg *Config) SanitizeGeminiKeys() {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -337,7 +339,7 @@ func (cfg *Config) SyncGeminiKeys() {
|
|||||||
}
|
}
|
||||||
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
entry.BaseURL = strings.TrimSpace(entry.BaseURL)
|
||||||
entry.ProxyURL = strings.TrimSpace(entry.ProxyURL)
|
entry.ProxyURL = strings.TrimSpace(entry.ProxyURL)
|
||||||
entry.Headers = normalizeHeaders(entry.Headers)
|
entry.Headers = NormalizeHeaders(entry.Headers)
|
||||||
if _, exists := seen[entry.APIKey]; exists {
|
if _, exists := seen[entry.APIKey]; exists {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -380,7 +382,8 @@ func looksLikeBcrypt(s string) bool {
|
|||||||
return len(s) > 4 && (s[:4] == "$2a$" || s[:4] == "$2b$" || s[:4] == "$2y$")
|
return len(s) > 4 && (s[:4] == "$2a$" || s[:4] == "$2b$" || s[:4] == "$2y$")
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeHeaders(headers map[string]string) map[string]string {
|
// NormalizeHeaders trims header keys and values and removes empty pairs.
|
||||||
|
func NormalizeHeaders(headers map[string]string) map[string]string {
|
||||||
if len(headers) == 0 {
|
if len(headers) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user