From b69bdf838d93f5601af21d4513c6e9047638787d Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 26 May 2026 21:29:03 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E7=94=9F=E6=88=90=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E4=BD=BF=E7=94=A8=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E6=97=A5=E5=BA=8F=E5=88=97=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openflare_server/service/config_version.go | 20 +++++++++-- openflare_server/service/https_phase1_test.go | 36 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/openflare_server/service/config_version.go b/openflare_server/service/config_version.go index 35b3c45e..18697215 100644 --- a/openflare_server/service/config_version.go +++ b/openflare_server/service/config_version.go @@ -12,6 +12,7 @@ import ( "openflare/model" "regexp" "sort" + "strconv" "strings" "time" @@ -1270,11 +1271,24 @@ func checksumBundle(mainConfig string, routeConfig string, supportFiles []Suppor func nextVersionNumber(now time.Time) (string, error) { prefix := now.Format("20060102") - var count int64 - if err := model.DB.Model(&model.ConfigVersion{}).Where("version LIKE ?", prefix+"-%").Count(&count).Error; err != nil { + var latest model.ConfigVersion + err := model.DB. + Select("version"). + Where("version LIKE ?", prefix+"-%"). + Order("version desc"). + First(&latest).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Sprintf("%s-%03d", prefix, 1), nil + } + if err != nil { return "", err } - return fmt.Sprintf("%s-%03d", prefix, count+1), nil + suffix := strings.TrimPrefix(latest.Version, prefix+"-") + sequence, err := strconv.Atoi(suffix) + if err != nil { + return "", fmt.Errorf("invalid config version sequence %q: %w", latest.Version, err) + } + return fmt.Sprintf("%s-%03d", prefix, sequence+1), nil } func renderHTTPProxyServer(serverNames string, originURL string, originHost string, customHeaders []ProxyRouteCustomHeaderInput, cacheConfig routeCacheConfig, limitConfig routeLimitConfig, upstreamConfig routeUpstreamConfig, powEnabled bool, basicAuthEnabled bool, basicAuthUsername string, basicAuthPassword string, cfg openRestyConfigSnapshot) string { diff --git a/openflare_server/service/https_phase1_test.go b/openflare_server/service/https_phase1_test.go index 7f02c5e2..94f90a82 100644 --- a/openflare_server/service/https_phase1_test.go +++ b/openflare_server/service/https_phase1_test.go @@ -102,6 +102,42 @@ func TestCreateTLSCertificateAndRenderHTTPSConfig(t *testing.T) { } } +func TestNextVersionNumberUsesMaxDailySequence(t *testing.T) { + setupServiceTestDB(t) + + seed := []model.ConfigVersion{ + { + Version: "20260526-001", + SnapshotJSON: "{}", + RenderedConfig: "server {}", + SupportFilesJSON: "[]", + Checksum: "checksum-1", + CreatedBy: "root", + }, + { + Version: "20260526-003", + SnapshotJSON: "{}", + RenderedConfig: "server {}", + SupportFilesJSON: "[]", + Checksum: "checksum-3", + CreatedBy: "root", + }, + } + for _, version := range seed { + if err := model.DB.Create(&version).Error; err != nil { + t.Fatalf("failed to seed config version %s: %v", version.Version, err) + } + } + + next, err := nextVersionNumber(time.Date(2026, 5, 26, 12, 0, 0, 0, time.Local)) + if err != nil { + t.Fatalf("nextVersionNumber failed: %v", err) + } + if next != "20260526-004" { + t.Fatalf("expected next version to follow max suffix, got %s", next) + } +} + func TestCreateProxyRouteRejectsHTTPSWithoutCertificate(t *testing.T) { setupServiceTestDB(t)