Repository: theupdateframework/go-tuf
Pull request #685 (2025-05-06 12:36:21)

Added back timeout to the fetcher DownloadFile method to avoid a breaking change.
The argument is documented as not used/deprecated.


Patch:
diff --git a/metadata/fetcher/fetcher.go b/metadata/fetcher/fetcher.go
index 07b9578..87198bf 100644
--- a/metadata/fetcher/fetcher.go
+++ b/metadata/fetcher/fetcher.go
@@ -37,7 +37,12 @@ type httpClient interface {
 
 // Fetcher interface
 type Fetcher interface {
-	DownloadFile(urlPath string, maxLength int64) ([]byte, error)
+	// DownloadFile downloads a file from the provided URL, reading
+	// up to maxLength of bytes before it aborts.
+	// The timeout argument is deprecated and not used. To configure
+	// the timeout (or retries), modify the fetcher instead. For the
+	// DefaultFetcher the underlying HTTP client can be substituted.
+	DownloadFile(urlPath string, maxLength int64, _ time.Duration) ([]byte, error)
 }
 
 // DefaultFetcher implements Fetcher
@@ -55,7 +60,7 @@ func (d *DefaultFetcher) SetHTTPUserAgent(httpUserAgent string) {
 
 // DownloadFile downloads a file from urlPath, errors out if it failed,
 // its length is larger than maxLength or the timeout is reached.
-func (d *DefaultFetcher) DownloadFile(urlPath string, maxLength int64) ([]byte, error) {
+func (d *DefaultFetcher) DownloadFile(urlPath string, maxLength int64, _ time.Duration) ([]byte, error) {
 	req, err := http.NewRequest("GET", urlPath, nil)
 	if err != nil {
 		return nil, err
diff --git a/metadata/updater/updater.go b/metadata/updater/updater.go
index 108d35c..4ab24d2 100644
--- a/metadata/updater/updater.go
+++ b/metadata/updater/updater.go
@@ -245,7 +245,7 @@ func (update *Updater) DownloadTarget(targetFile *metadata.TargetFiles, filePath
 		}
 	}
 	fullURL := fmt.Sprintf("%s%s", targetBaseURL, targetRemotePath)
-	data, err := update.cfg.Fetcher.DownloadFile(fullURL, targetFile.Length)
+	data, err := update.cfg.Fetcher.DownloadFile(fullURL, targetFile.Length, 0)
 	if err != nil {
 		return "", nil, err
 	}
@@ -648,7 +648,7 @@ func (update *Updater) downloadMetadata(roleName string, length int64, version s
 	} else {
 		urlPath = fmt.Sprintf("%s%s.%s.json", urlPath, version, url.PathEscape(roleName))
 	}
-	return update.cfg.Fetcher.DownloadFile(urlPath, length)
+	return update.cfg.Fetcher.DownloadFile(urlPath, length, 0)
 }
 
 // generateTargetFilePath generates path from TargetFiles


Test patch:
diff --git a/internal/testutils/simulator/repository_simulator.go b/internal/testutils/simulator/repository_simulator.go
index 7494fc0..1bbf785 100644
--- a/internal/testutils/simulator/repository_simulator.go
+++ b/internal/testutils/simulator/repository_simulator.go
@@ -303,7 +303,7 @@ func partition(s string, delimiter string) (string, string) {
 	return version, role
 }
 
-func (rs *RepositorySimulator) DownloadFile(urlPath string, maxLength int64) ([]byte, error) {
+func (rs *RepositorySimulator) DownloadFile(urlPath string, maxLength int64, _ time.Duration) ([]byte, error) {
 	data, err := rs.fetch(urlPath)
 	if err != nil {
 		return data, err
diff --git a/metadata/fetcher/fetcher_test.go b/metadata/fetcher/fetcher_test.go
index 51fc67e..330919d 100644
--- a/metadata/fetcher/fetcher_test.go
+++ b/metadata/fetcher/fetcher_test.go
@@ -85,7 +85,7 @@ func TestDownLoadFile(t *testing.T) {
 			// run the function under test
 			fetcher := NewDefaultFetcher()
 			fetcher.SetHTTPUserAgent("Metadata_Unit_Test/1.0")
-			data, err := fetcher.DownloadFile(tt.url, tt.maxLength)
+			data, err := fetcher.DownloadFile(tt.url, tt.maxLength, 0)
 			// special case if we expect no error
 			if tt.wantErr == nil {
 				assert.NoErrorf(t, err, "expected no error but got %v", err)
@@ -156,7 +156,7 @@ func TestDownloadFile_Retry(t *testing.T) {
 					backoff.WithMaxTries(3),
 				},
 			}
-			data, err := fetcher.DownloadFile("https://jku.github.io/tuf-demo/metadata/1.root.json", 512000)
+			data, err := fetcher.DownloadFile("https://jku.github.io/tuf-demo/metadata/1.root.json", 512000, 0)
 			if tt.shouldSucceed {
 				assert.Equal(t, sampleRootData, data)
 				assert.NoError(t, err)