Browse Source

new updating code

Alan Shreve 11 years ago
parent
commit
94c87f1a79
1 changed files with 64 additions and 87 deletions
  1. 64 87
      src/ngrok/client/update_release.go

+ 64 - 87
src/ngrok/client/update_release.go

@@ -4,120 +4,97 @@ package client
 
 
 import (
 import (
 	update "github.com/inconshreveable/go-update"
 	update "github.com/inconshreveable/go-update"
-	"net/http"
-	"net/url"
+	"github.com/inconshreveable/go-update/check"
 	"ngrok/client/mvc"
 	"ngrok/client/mvc"
 	"ngrok/log"
 	"ngrok/log"
 	"ngrok/version"
 	"ngrok/version"
-	"runtime"
 	"time"
 	"time"
 )
 )
 
 
 const (
 const (
-	updateEndpoint = "https://dl.ngrok.com/update"
-	checkEndpoint  = "https://dl.ngrok.com/update/check"
+	//updateEndpoint = "https://api.equinox.io/1/Applications/%s/Update"
+	updateEndpoint = "http://localhost:8889/1/Applications/%s/Update"
 )
 )
 
 
-func progressWatcher(s mvc.State, progress chan int, complete chan int) {
-	for {
-		select {
-		case pct, ok := <-progress:
-			if !ok {
-				close(complete)
-				return
-			} else if pct == 100 {
-				s.SetUpdateStatus(mvc.UpdateInstalling)
-				close(complete)
-				return
-			} else {
-				if pct%25 == 0 {
-					log.Info("Downloading update %d%% complete", pct)
-				}
-				s.SetUpdateStatus(mvc.UpdateStatus(pct))
-			}
-		}
+var publicKey []byte = []byte(
+	`-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Gx8r9no1QBtCruJW2tu
+082MJJ5ZA7k803GisR2c6WglPOD1b/+kUg+dx5Y0TKXz+uNlR3GrCxLh8WkoA95M
+T38CQldIjoVN/bWP6jzFxL+6BRoKy5L1TcaIf3xb9B8OhwEq60cvFy7BBrLKEHJN
+ua/D1S5axgNOAJ8tQ2w8gISICd84ng+U9tNMqIcEjUN89h3Z4zablfNIfVkbqbSR
+fnkR9boUaMr6S1w8OeInjWdiab9sUr87GmEo/3tVxrHVCzHB8pzzoZceCkjgI551
+d/hHfAl567YhlkQMNz8dawxBjQwCHHekgC8gAvTO7kmXkAm6YAbpa9kjwgnorPEP
+ywIDAQAB
+-----END PUBLIC KEY-----`)
+var u *update.Update
+
+func init() {
+	var err error
+	u, err = update.New().VerifySignatureWithPEM(publicKey)
+	if err != nil {
+		panic(err)
 	}
 	}
 }
 }
 
 
 func autoUpdate(s mvc.State, token string) {
 func autoUpdate(s mvc.State, token string) {
-	tryAgain := true
-
-	params := make(url.Values)
-	params.Add("version", version.MajorMinor())
-	params.Add("os", runtime.GOOS)
-	params.Add("arch", runtime.GOARCH)
-	params.Add("user", token)
-
-	updateUrl := updateEndpoint + "?" + params.Encode()
-	checkUrl := checkEndpoint + "?" + params.Encode()
-
-	update := func() {
+	update := func() (tryAgain bool) {
 		log.Info("Checking for update")
 		log.Info("Checking for update")
-		available, err := update.NewDownload(checkUrl).Check()
-		if err != nil {
-			log.Error("Error while checking for update: %v", err)
-			return
+		params := check.Params{
+			Version: 1,
+			// XXX AppId: appId,
+			AppVersion: version.MajorMinor(),
+			UserId:     token,
 		}
 		}
 
 
-		if !available {
+		result, err := params.CheckForUpdate(updateEndpoint)
+		if err == check.NoUpdateAvailable {
 			log.Info("No update available")
 			log.Info("No update available")
-			return
+			return true
+		} else if err != nil {
+			log.Error("Error while checking for update: %v", err)
+			return true
 		}
 		}
 
 
-		// stop trying after a single download attempt
-		// XXX: improve this so the we can:
-		// 1. safely update multiple times
-		// 2. only retry after a network connection failure
-		tryAgain = false
-
-		download := update.NewDownload(updateUrl)
-		downloadComplete := make(chan int)
-
-		go progressWatcher(s, download.Progress, downloadComplete)
-
-		log.Info("Trying to update . . .")
-		err, errRecover := download.GetAndUpdate()
-		<-downloadComplete
-
-		if err != nil {
-			// log error to console
-			log.Error("Error while updating ngrok: %v", err)
-			if errRecover != nil {
-				log.Error("Error while recovering from failed ngrok update, your binary may be missing: %v", errRecover.Error())
-				params.Add("errorRecover", errRecover.Error())
-			}
-
-			// log error to ngrok.com's servers for debugging purposes
-			params.Add("error", err.Error())
-			resp, reportErr := http.PostForm("https://dl.ngrok.com/update/error", params)
-			if err != nil {
-				log.Error("Error while reporting update error: %v, %v", err, reportErr)
-			}
-			resp.Body.Close()
-
-			// tell the user to update manually
+		if result.Initiative == check.INITIATIVE_AUTO {
+			applyUpdate(s, result)
+		} else if result.Initiative == check.INITIATIVE_MANUAL {
+			// this is the way the server tells us to update manually
+			log.Info("Server wants us to update manually")
 			s.SetUpdateStatus(mvc.UpdateAvailable)
 			s.SetUpdateStatus(mvc.UpdateAvailable)
 		} else {
 		} else {
-			if !download.Available {
-				// this is the way the server tells us to update manually
-				log.Info("Server wants us to update manually")
-				s.SetUpdateStatus(mvc.UpdateAvailable)
-			} else {
-				// tell the user the update is ready
-				log.Info("Update ready!")
-				s.SetUpdateStatus(mvc.UpdateReady)
-			}
+			log.Info("Update available, but ignoring")
 		}
 		}
 
 
-		return
+		// stop trying after a single download attempt
+		// XXX: improve this so the we can:
+		// 1. safely update multiple times
+		// 2. only retry after temporary errors
+		return false
 	}
 	}
 
 
 	// try to update immediately and then at a set interval
 	// try to update immediately and then at a set interval
-	update()
-	for _ = range time.Tick(updateCheckInterval) {
-		if !tryAgain {
+	for {
+		if tryAgain := update(); !tryAgain {
 			break
 			break
 		}
 		}
-		update()
+
+		time.Sleep(updateCheckInterval)
 	}
 	}
 }
 }
+
+func applyUpdate(s mvc.State, result *check.Result) {
+	err, errRecover := result.Update(u)
+	if err == nil {
+		log.Info("Update ready!")
+		s.SetUpdateStatus(mvc.UpdateReady)
+		return
+	}
+
+	log.Error("Error while updating ngrok: %v", err)
+	if errRecover != nil {
+		log.Error("Error while recovering from failed ngrok update, your binary may be missing: %v", errRecover.Error())
+	}
+
+	// tell the user to update manually
+	s.SetUpdateStatus(mvc.UpdateAvailable)
+}