From 54d276447ed24ebebfd1425cf21ce653a49ecb9f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Nov 2025 11:22:21 +0000 Subject: [PATCH] Refactor: Avoid network requests when health check is disabled This change ensures that when a site's health check is disabled, the checker returns cached metadata without making any network requests, as per issue #1446. A new helper function `getExistingSiteSnapshot` is introduced to retrieve this cached information. A new test case `TestCheckSiteSkipsNetworkWhenDisabled` is added to verify this behavior. Co-authored-by: jacky-943572677 --- internal/sitecheck/checker.go | 37 ++++++++++++++++------- internal/sitecheck/checker_test.go | 48 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 internal/sitecheck/checker_test.go diff --git a/internal/sitecheck/checker.go b/internal/sitecheck/checker.go index 35235f9d7..10f583191 100644 --- a/internal/sitecheck/checker.go +++ b/internal/sitecheck/checker.go @@ -293,24 +293,25 @@ func (sc *SiteChecker) CheckSite(ctx context.Context, siteURL string) (*SiteInfo // Try enhanced health check first if config exists config, err := LoadSiteConfig(siteURL) - // If health check is disabled, return a SiteInfo without status + // If health check is disabled, return cached metadata without issuing any network requests (#1446) if err == nil && config != nil && !config.HealthCheckEnabled { - protocol := "http" - if config.HealthCheckConfig != nil && config.HealthCheckConfig.Protocol != "" { - protocol = config.HealthCheckConfig.Protocol - } - siteInfo := &SiteInfo{ SiteConfig: *config, Name: extractDomainName(siteURL), Title: config.DisplayURL, } - // Try to get favicon if enabled and not a gRPC check - if sc.options.CheckFavicon && !isGRPCProtocol(protocol) { - faviconURL, faviconData := sc.tryGetFavicon(ctx, siteURL) - siteInfo.FaviconURL = faviconURL - siteInfo.FaviconData = faviconData + if existing := sc.getExistingSiteSnapshot(siteURL); existing != nil { + siteInfo.FaviconURL = existing.FaviconURL + siteInfo.FaviconData = existing.FaviconData + siteInfo.Status = existing.Status + siteInfo.StatusCode = existing.StatusCode + siteInfo.ResponseTime = existing.ResponseTime + siteInfo.LastChecked = existing.LastChecked + siteInfo.Error = existing.Error + if siteInfo.Title == "" { + siteInfo.Title = existing.Title + } } return siteInfo, nil @@ -522,6 +523,20 @@ func (sc *SiteChecker) GetSitesList() []*SiteInfo { return result } +// getExistingSiteSnapshot returns a copy of the last known site info, if present. +func (sc *SiteChecker) getExistingSiteSnapshot(siteURL string) *SiteInfo { + sc.mu.RLock() + defer sc.mu.RUnlock() + + existing, ok := sc.sites[siteURL] + if !ok || existing == nil { + return nil + } + + clone := *existing + return &clone +} + // extractDomainName extracts domain name from URL func extractDomainName(siteURL string) string { parsed, err := url.Parse(siteURL) diff --git a/internal/sitecheck/checker_test.go b/internal/sitecheck/checker_test.go new file mode 100644 index 000000000..0d0601400 --- /dev/null +++ b/internal/sitecheck/checker_test.go @@ -0,0 +1,48 @@ +package sitecheck + +import ( + "context" + "net/http" + "testing" + + "github.com/0xJacky/Nginx-UI/model" +) + +type roundTripFunc func(*http.Request) (*http.Response, error) + +func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return f(req) +} + +func TestCheckSiteSkipsNetworkWhenDisabled(t *testing.T) { + t.Cleanup(InvalidateSiteConfigCache) + + options := DefaultCheckOptions() + checker := NewSiteChecker(options) + + // Any HTTP request made by the checker should fail this test. + checker.client = &http.Client{ + Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) { + t.Fatalf("unexpected HTTP request to %s while health check is disabled", req.URL.String()) + return nil, nil + }), + } + + const siteURL = "https://example.com" + config := &model.SiteConfig{ + Model: model.Model{ID: 1}, + Host: "example.com:443", + Scheme: "https", + DisplayURL: siteURL, + HealthCheckEnabled: false, + HealthCheckConfig: &model.HealthCheckConfig{ + Protocol: "https", + }, + } + + setCachedSiteConfig(config.Host, config) + + if _, err := checker.CheckSite(context.Background(), siteURL); err != nil { + t.Fatalf("CheckSite returned error: %v", err) + } +}