X Tutup
Skip to content

Commit 8e31184

Browse files
committed
Ensure that we never download "legacy" archive formats
The `zipball_url` and `tarball_url` fields on the Release API payload always link to "legacy" archives that are of a different format than those one would get if they downloaded an archive from a Release using the web interface. The GitHub API does not seem to publish links to non-legacy archives. This adds a redirect hack to turn "legacy" Codeload URLs into non-legacy ones with the goal of ensuring the consistency of user experience when downloading archives.
1 parent 8058c4e commit 8e31184

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

pkg/cmd/release/download/download.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"os"
1010
"path/filepath"
11+
"regexp"
1112

1213
"github.com/MakeNowJust/heredoc"
1314
"github.com/cli/cli/v2/api"
@@ -228,9 +229,19 @@ func downloadAsset(httpClient *http.Client, assetURL, destinationDir string, fil
228229
}
229230

230231
req.Header.Set("Accept", "application/octet-stream")
231-
// adding application/json to Accept header due to a bug in the zipball/tarball API endpoint that makes it mandatory
232232
if isArchive {
233+
// adding application/json to Accept header due to a bug in the zipball/tarball API endpoint that makes it mandatory
233234
req.Header.Set("Accept", "application/octet-stream, application/json")
235+
236+
// override HTTP redirect logic to avoid "legacy" Codeload resources
237+
oldClient := *httpClient
238+
httpClient = &oldClient
239+
httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
240+
if len(via) == 1 {
241+
req.URL.Path = removeLegacyFromCodeloadPath(req.URL.Path)
242+
}
243+
return nil
244+
}
234245
}
235246

236247
resp, err := httpClient.Do(req)
@@ -268,3 +279,16 @@ func downloadAsset(httpClient *http.Client, assetURL, destinationDir string, fil
268279
_, err = io.Copy(f, resp.Body)
269280
return err
270281
}
282+
283+
var codeloadLegacyRE = regexp.MustCompile(`^(/[^/]+/[^/]+/)legacy\.`)
284+
285+
// removeLegacyFromCodeloadPath converts URLs for "legacy" Codeload archives into ones that match the format
286+
// when you choose to download "Source code (zip/tar.gz)" from a tagged release on the web. The legacy URLs
287+
// look like this:
288+
//
289+
// https://codeload.github.com/OWNER/REPO/legacy.zip/refs/tags/TAGNAME
290+
//
291+
// Removing the "legacy." part results in a valid Codeload URL for our desired archive format.
292+
func removeLegacyFromCodeloadPath(p string) string {
293+
return codeloadLegacyRE.ReplaceAllString(p, "$1")
294+
}

0 commit comments

Comments
 (0)
X Tutup