Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNebulosa <85841412+nebulosa2007@users.noreply.github.com>2026-02-03 01:20:57 +0300
committerGitHub <noreply@github.com>2026-02-03 01:20:57 +0300
commit03f04194f2dc2f4ab45a996c3afceb61241e73ea (patch)
treed2a9136570bd858191916a9f2bde32ff73098eab /web/service
parent248700a8a3c58b74b0d1d6c7e5d17ab32f4a751d (diff)
Update geofiles according 304 http respond (#3690)
* feat: enhance geofile update process with conditional GET and modification time handling * style: improve formatting in UpdateGeofile function
Diffstat (limited to 'web/service')
-rw-r--r--web/service/server.go51
1 files changed, 49 insertions, 2 deletions
diff --git a/web/service/server.go b/web/service/server.go
index ce9374c8..ec217e29 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -1087,13 +1087,60 @@ func (s *ServerService) UpdateGeofile(fileName string) error {
return common.NewErrorf("Invalid geofile name: %s not in allowlist", fileName)
}
}
+
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 +1152,7 @@ func (s *ServerService) UpdateGeofile(fileName string) error {
return common.NewErrorf("Failed to save Geofile %s: %v", destPath, err)
}
+ updateFileModTime()
return nil
}
@@ -1114,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))
}