mirror of
https://github.com/MedzikUser/go-github-selfupdate.git
synced 2024-08-15 03:25:29 +00:00
fix handling redirection of GitHub download asset API
This commit is contained in:
parent
6b4eeadeb7
commit
d98ca18787
2 changed files with 35 additions and 16 deletions
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
func readAndUpdate(src io.ReadCloser, assetURL, cmdPath string) error {
|
||||
func uncompressAndUpdate(src io.ReadCloser, assetURL, cmdPath string) error {
|
||||
defer src.Close()
|
||||
|
||||
_, cmd := filepath.Split(cmdPath)
|
||||
|
@ -28,21 +28,23 @@ func readAndUpdate(src io.ReadCloser, assetURL, cmdPath string) error {
|
|||
})
|
||||
}
|
||||
|
||||
// UpdateTo downloads an executable from assetURL and replace the current binary with the downloaded one.
|
||||
// This function is low-level API to update the binary. Because it does not use GitHub API and downloads asset directly from the URL via HTTP,
|
||||
// this function is not available to update a release for private repositories.
|
||||
// cmdPath is a file path to command executable.
|
||||
func UpdateTo(assetURL, cmdPath string) error {
|
||||
res, err := http.Get(assetURL)
|
||||
func (up *Updater) downloadDirectlyFromURL(assetURL string) (io.ReadCloser, error) {
|
||||
req, err := http.NewRequest("GET", assetURL, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to download a release file from %s: %s", assetURL, err)
|
||||
return nil, fmt.Errorf("Failed to create HTTP request to %s: %s", assetURL, err)
|
||||
}
|
||||
|
||||
req.Header.Add("Accept", "application/octet-stream")
|
||||
res, err := up.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to download a release file from %s: %s", assetURL, err)
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
return fmt.Errorf("Failed to download a release file from %s", assetURL)
|
||||
return nil, fmt.Errorf("Failed to download a release file from %s", assetURL)
|
||||
}
|
||||
|
||||
return readAndUpdate(res.Body, assetURL, cmdPath)
|
||||
return res.Body, nil
|
||||
}
|
||||
|
||||
// UpdateTo downloads an executable from GitHub Releases API and replace current binary with the downloaded one.
|
||||
|
@ -55,9 +57,12 @@ func (up *Updater) UpdateTo(rel *Release, cmdPath string) error {
|
|||
}
|
||||
if redirectURL != "" {
|
||||
log.Println("Redirect URL was returned while trying to download a release asset from GitHub API. Falling back to downloading from asset URL directly:", redirectURL)
|
||||
return UpdateTo(redirectURL, cmdPath)
|
||||
src, err = up.downloadDirectlyFromURL(redirectURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return readAndUpdate(src, rel.AssetURL, cmdPath)
|
||||
return uncompressAndUpdate(src, rel.AssetURL, cmdPath)
|
||||
}
|
||||
|
||||
// UpdateCommand updates a given command binary to the latest version.
|
||||
|
@ -109,6 +114,19 @@ func (up *Updater) UpdateSelf(current semver.Version, slug string) (*Release, er
|
|||
return UpdateCommand(cmdPath, current, slug)
|
||||
}
|
||||
|
||||
// UpdateTo downloads an executable from assetURL and replace the current binary with the downloaded one.
|
||||
// This function is low-level API to update the binary. Because it does not use GitHub API and downloads asset directly from the URL via HTTP,
|
||||
// this function is not available to update a release for private repositories.
|
||||
// cmdPath is a file path to command executable.
|
||||
func UpdateTo(assetURL, cmdPath string) error {
|
||||
up := NewUpdater(Config{})
|
||||
src, err := up.downloadDirectlyFromURL(assetURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return uncompressAndUpdate(src, assetURL, cmdPath)
|
||||
}
|
||||
|
||||
// UpdateCommand updates a given command binary to the latest version.
|
||||
// This function is a shortcut version of updater.UpdateCommand.
|
||||
func UpdateCommand(cmdPath string, current semver.Version, slug string) (*Release, error) {
|
||||
|
|
|
@ -13,8 +13,9 @@ import (
|
|||
// Updater is responsible for managing the context of self-update.
|
||||
// It contains GitHub client and its context.
|
||||
type Updater struct {
|
||||
api *github.Client
|
||||
apiCtx context.Context
|
||||
api *github.Client
|
||||
apiCtx context.Context
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// Config represents the configuration of self-update.
|
||||
|
@ -35,12 +36,12 @@ func NewUpdater(config Config) *Updater {
|
|||
}
|
||||
ctx := context.Background()
|
||||
|
||||
var auth *http.Client
|
||||
auth := http.DefaultClient
|
||||
if token != "" {
|
||||
src := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
|
||||
auth = oauth2.NewClient(ctx, src)
|
||||
}
|
||||
|
||||
client := github.NewClient(auth)
|
||||
return &Updater{client, ctx}
|
||||
return &Updater{client, ctx, auth}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue