From 2e01ff19f7da5d256e9accb65db613a32b1261e3 Mon Sep 17 00:00:00 2001 From: Nebulosa Date: Thu, 22 Jan 2026 00:25:32 +0300 Subject: [PATCH 1/2] feat: enhance geofile update process with conditional GET and modification time handling --- web/service/server.go | 48 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/web/service/server.go b/web/service/server.go index ead3e2f0..fae1c66a 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -1088,12 +1088,57 @@ func (s *ServerService) UpdateGeofile(fileName string) error { } } downloadFile := func(url, destPath string) error { - resp, err := http.Get(url) + var req *http.Request + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return common.NewErrorf("Failed to create HTTP request for %s: %v", url, err) + } + var localFileModTime time.Time + if fileInfo, err := os.Stat(destPath); err == nil { + localFileModTime = fileInfo.ModTime() + if !localFileModTime.IsZero() { + req.Header.Set("If-Modified-Since", localFileModTime.UTC().Format(http.TimeFormat)) + } + } + + client := &http.Client{} + resp, err := client.Do(req) if err != nil { return common.NewErrorf("Failed to download Geofile from %s: %v", url, err) } defer resp.Body.Close() + // Parse Last-Modified header from server + var serverModTime time.Time + serverModTimeStr := resp.Header.Get("Last-Modified") + if serverModTimeStr != "" { + parsedTime, err := time.Parse(http.TimeFormat, serverModTimeStr) + if err != nil { + logger.Warningf("Failed to parse Last-Modified header for %s: %v", url, err) + } else { + serverModTime = parsedTime + } + } + + // Function to update local file's modification time + updateFileModTime := func() { + if !serverModTime.IsZero() { + if err := os.Chtimes(destPath, serverModTime, serverModTime); err != nil { + logger.Warningf("Failed to update modification time for %s: %v", destPath, err) + } + } + } + + // Handle 304 Not Modified + if resp.StatusCode == http.StatusNotModified { + updateFileModTime() + return nil + } + + if resp.StatusCode != http.StatusOK { + return common.NewErrorf("Failed to download Geofile from %s: received status code %d", url, resp.StatusCode) + } + file, err := os.Create(destPath) if err != nil { return common.NewErrorf("Failed to create Geofile %s: %v", destPath, err) @@ -1105,6 +1150,7 @@ func (s *ServerService) UpdateGeofile(fileName string) error { return common.NewErrorf("Failed to save Geofile %s: %v", destPath, err) } + updateFileModTime() return nil } From 41d0278ed22dfbfdc9cbf65d09b2ace927d78bac Mon Sep 17 00:00:00 2001 From: Nebulosa Date: Mon, 2 Feb 2026 11:10:02 +0300 Subject: [PATCH 2/2] style: improve formatting in UpdateGeofile function --- web/service/server.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/service/server.go b/web/service/server.go index 793f541b..ec217e29 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -1087,12 +1087,14 @@ func (s *ServerService) UpdateGeofile(fileName string) error { return common.NewErrorf("Invalid geofile name: %s not in allowlist", fileName) } } + downloadFile := func(url, destPath string) error { var req *http.Request req, err := http.NewRequest("GET", url, nil) if err != nil { - return common.NewErrorf("Failed to create HTTP request for %s: %v", url, err) + return common.NewErrorf("Failed to create HTTP request for %s: %v", url, err) } + var localFileModTime time.Time if fileInfo, err := os.Stat(destPath); err == nil { localFileModTime = fileInfo.ModTime() @@ -1100,7 +1102,7 @@ func (s *ServerService) UpdateGeofile(fileName string) error { req.Header.Set("If-Modified-Since", localFileModTime.UTC().Format(http.TimeFormat)) } } - + client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -1160,7 +1162,6 @@ func (s *ServerService) UpdateGeofile(fileName string) error { for _, file := range files { // Sanitize the filename from our allowlist as an extra precaution destPath := filepath.Join(config.GetBinFolderPath(), filepath.Base(file.FileName)) - if err := downloadFile(file.URL, destPath); err != nil { errorMessages = append(errorMessages, fmt.Sprintf("Error downloading Geofile '%s': %v", file.FileName, err)) }