Skip to content

Commit 84fa497

Browse files
committed
fix(server): snapshot config with YAML to handle in-place mutations
- Add oldConfigYaml to store previous config snapshot - Rebuild oldCfg from YAML in UpdateClients for reliable change detection - Initialize and refresh snapshot on startup and after updates - Prevents change detection bugs when Management API mutates cfg in place - Import gopkg.in/yaml.v3
1 parent b641d90 commit 84fa497

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

internal/api/server.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/router-for-me/CLIProxyAPI/v6/sdk/api/handlers/openai"
3333
"github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
3434
log "github.com/sirupsen/logrus"
35+
"gopkg.in/yaml.v3"
3536
)
3637

3738
const oauthCallbackSuccessHTML = `<html><head><meta charset="utf-8"><title>Authentication successful</title><script>setTimeout(function(){window.close();},5000);</script></head><body><h1>Authentication successful!</h1><p>You can close this window.</p><p>This window will close automatically in 5 seconds.</p></body></html>`
@@ -116,6 +117,10 @@ type Server struct {
116117
// cfg holds the current server configuration.
117118
cfg *config.Config
118119

120+
// oldConfigYaml stores a YAML snapshot of the previous configuration for change detection.
121+
// This prevents issues when the config object is modified in place by Management API.
122+
oldConfigYaml []byte
123+
119124
// accessManager handles request authentication providers.
120125
accessManager *sdkaccess.Manager
121126

@@ -220,6 +225,8 @@ func NewServer(cfg *config.Config, authManager *auth.Manager, accessManager *sdk
220225
currentPath: wd,
221226
envManagementSecret: envManagementSecret,
222227
}
228+
// Save initial YAML snapshot
229+
s.oldConfigYaml, _ = yaml.Marshal(cfg)
223230
s.applyAccessConfig(nil, cfg)
224231
// Initialize management handler
225232
s.mgmt = managementHandlers.NewHandler(cfg, configFilePath, authManager)
@@ -654,7 +661,11 @@ func (s *Server) applyAccessConfig(oldCfg, newCfg *config.Config) {
654661
// - clients: The new slice of AI service clients
655662
// - cfg: The new application configuration
656663
func (s *Server) UpdateClients(cfg *config.Config) {
657-
oldCfg := s.cfg
664+
// Reconstruct old config from YAML snapshot to avoid reference sharing issues
665+
var oldCfg *config.Config
666+
if len(s.oldConfigYaml) > 0 {
667+
_ = yaml.Unmarshal(s.oldConfigYaml, &oldCfg)
668+
}
658669

659670
// Update request logger enabled state if it has changed
660671
previousRequestLog := false
@@ -735,6 +746,8 @@ func (s *Server) UpdateClients(cfg *config.Config) {
735746

736747
s.applyAccessConfig(oldCfg, cfg)
737748
s.cfg = cfg
749+
// Save YAML snapshot for next comparison
750+
s.oldConfigYaml, _ = yaml.Marshal(cfg)
738751
s.handlers.UpdateClients(&cfg.SDKConfig)
739752

740753
if !cfg.RemoteManagement.DisableControlPanel {

0 commit comments

Comments
 (0)