diff --git a/selfupdate/selfupdate.go b/selfupdate/selfupdate.go index 4871c90..18a4856 100644 --- a/selfupdate/selfupdate.go +++ b/selfupdate/selfupdate.go @@ -36,6 +36,7 @@ import ( "io/ioutil" "log" "math/rand" + "net/url" "os" "path/filepath" "runtime" @@ -179,7 +180,7 @@ func (u *Updater) update() error { } func (u *Updater) fetchInfo() error { - r, err := u.fetch(u.ApiURL + u.CmdName + "/" + plat + ".json") + r, err := u.fetch(u.ApiURL + url.QueryEscape(u.CmdName) + "/" + url.QueryEscape(plat) + ".json") if err != nil { return err } @@ -206,7 +207,7 @@ func (u *Updater) fetchAndVerifyPatch(old io.Reader) ([]byte, error) { } func (u *Updater) fetchAndApplyPatch(old io.Reader) ([]byte, error) { - r, err := u.fetch(u.DiffURL + u.CmdName + "/" + u.CurrentVersion + "/" + u.Info.Version + "/" + plat) + r, err := u.fetch(u.DiffURL + url.QueryEscape(u.CmdName) + "/" + url.QueryEscape(u.CurrentVersion) + "/" + url.QueryEscape(u.Info.Version) + "/" + url.QueryEscape(plat)) if err != nil { return nil, err } @@ -229,7 +230,7 @@ func (u *Updater) fetchAndVerifyFullBin() ([]byte, error) { } func (u *Updater) fetchBin() ([]byte, error) { - r, err := u.fetch(u.BinURL + u.CmdName + "/" + u.Info.Version + "/" + plat + ".gz") + r, err := u.fetch(u.BinURL + url.QueryEscape(u.CmdName) + "/" + url.QueryEscape(u.Info.Version) + "/" + url.QueryEscape(plat) + ".gz") if err != nil { return nil, err } diff --git a/selfupdate/selfupdate_test.go b/selfupdate/selfupdate_test.go index 9d8ada2..6def191 100644 --- a/selfupdate/selfupdate_test.go +++ b/selfupdate/selfupdate_test.go @@ -24,10 +24,9 @@ func TestUpdaterFetchMustReturnNonNilReaderCloser(t *testing.T) { t.Log("Expected an error") t.Fail() } - } -func TestUpdaterWithEmptyPaloadNoErrorNoUpdate(t *testing.T) { +func TestUpdaterWithEmptyPayloadNoErrorNoUpdate(t *testing.T) { mr := &mockRequester{} mr.handleRequest( func(url string) (io.ReadCloser, error) { @@ -38,9 +37,23 @@ func TestUpdaterWithEmptyPaloadNoErrorNoUpdate(t *testing.T) { err := updater.BackgroundRun() if err != nil { - t.Errorf("Error occured: %#v", err) + t.Errorf("Error occurred: %#v", err) } +} +func TestUpdaterWithEmptyPayloadNoErrorNoUpdateEscapedPath(t *testing.T) { + mr := &mockRequester{} + mr.handleRequest( + func(url string) (io.ReadCloser, error) { + equals(t, "http://updates.yourdomain.com/myapp%2Bfoo/darwin-amd64.json", url) + return newTestReaderCloser("{}"), nil + }) + updater := createUpdaterWithEscapedCharacters(mr) + + err := updater.BackgroundRun() + if err != nil { + t.Errorf("Error occurred: %#v", err) + } } func createUpdater(mr *mockRequester) *Updater { @@ -55,6 +68,18 @@ func createUpdater(mr *mockRequester) *Updater { } } +func createUpdaterWithEscapedCharacters(mr *mockRequester) *Updater { + return &Updater{ + CurrentVersion: "1.2+foobar", + ApiURL: "http://updates.yourdomain.com/", + BinURL: "http://updates.yourdownmain.com/", + DiffURL: "http://updates.yourdomain.com/", + Dir: "update/", + CmdName: "myapp+foo", // app name + Requester: mr, + } +} + func equals(t *testing.T, expected, actual interface{}) { if expected != actual { t.Log(fmt.Sprintf("Expected: %#v %#v\n", expected, actual))