diff --git a/src/cli.go b/src/cli.go index a588af7..4235e12 100644 --- a/src/cli.go +++ b/src/cli.go @@ -159,9 +159,9 @@ func GetApp() cli.App { config_show := cli.NewCommand("show", "print current config"). WithAction(func(args []string, options map[string]string) int { p := getPersistance(options) - remote := p.State.RemoteHostname - if remote == "" { - remote = "(None)" + remote := "(None)" + if p.State.RemoteURL != nil { + remote = p.State.RemoteURL.Host } fmt.Printf("Encryption Key: \t%v\n", p.State.Key) @@ -231,10 +231,25 @@ func GetApp() cli.App { p := getPersistance(options) url, err := url.ParseRequestURI(host) - if err != nil { - p.State.RemoteHostname = "http://" + host + if err == nil { + // url parsed fine, use it + // ensure it's http(s) + if !strings.HasPrefix(url.Scheme, "http") { + url.Scheme = "https" + fmt.Println("Warning: only http(s) in URLs is supported, defaulting to https: ", url) + } + // ensure there's a terminal / + // note that this doesn't handle the escaped path or the raw path + if url.Path != "" && !strings.HasSuffix(url.Path, "/") { + url.Path += "/" + } + p.State.RemoteURL = url } else { - p.State.RemoteHostname = url.String() + // only warn if the user isn't intentionally unsetting the remote + if host != "" { + fmt.Println("Invalid url, unsetting remote: ", err.Error()) + } + p.State.RemoteURL = url } err = p.CommitState() @@ -266,7 +281,11 @@ func GetApp() cli.App { logger.Fatal("Key not found.") } - fmt.Println(p.State.RemoteHostname + "/get?q=" + entry.UrlToken) + u, _ := p.State.RemoteURL.Parse("get") // this should never fail + q := u.Query() + q.Set("q", entry.UrlToken) + u.RawQuery = q.Encode() + fmt.Println(u) return 0 }) qr := cli.NewCommand("qr", "print shareable qr code of entry to console"). @@ -289,9 +308,11 @@ func GetApp() cli.App { logger.Fatal("Key not found.") } - url := p.State.RemoteHostname + "/get?q=" + entry.UrlToken - - qrcode.QRCode(url, qrcode.BrightBlack, qrcode.BrightWhite, qr.Low) + url, _ := p.State.RemoteURL.Parse("get") // this should never fail + q := url.Query() + q.Set("q", entry.UrlToken) + url.RawQuery = q.Encode() + qrcode.QRCode(url.String(), qrcode.BrightBlack, qrcode.BrightWhite, qr.Low) return 0 }) diff --git a/src/sqlite_persistance.go b/src/sqlite_persistance.go index 6111ecc..6af4f94 100644 --- a/src/sqlite_persistance.go +++ b/src/sqlite_persistance.go @@ -17,16 +17,17 @@ import ( "modernc.org/mathutil" _ "modernc.org/sqlite" "net/http" + "net/url" "os" ) type SqliteState struct { - Counter uint64 - Pid uint32 - Key string - RemoteHostname string - RemoteCounter uint64 - SchemaVersion uint32 + Counter uint64 + Pid uint32 + Key string + RemoteURL *url.URL + RemoteCounter uint64 + SchemaVersion uint32 } type SqlitePersistance struct { @@ -36,7 +37,7 @@ type SqlitePersistance struct { } func (p *SqlitePersistance) GetRemoteUpdates() (err error) { - if p.State.RemoteHostname == "" { + if p.State.RemoteURL == nil { return nil } request, err := json.Marshal(UpdateRequest{ProcessID: p.State.Pid, Counter: p.State.RemoteCounter}) @@ -49,7 +50,11 @@ func (p *SqlitePersistance) GetRemoteUpdates() (err error) { return err } - resp, err := http.Post(p.State.RemoteHostname+"/pull", "application/json", bytes.NewReader(request)) + pull, err := p.State.RemoteURL.Parse("pull") + if err != nil { + panic(err) + } + resp, err := http.Post(pull.String(), "application/json", bytes.NewReader(request)) if err != nil { return err } @@ -81,9 +86,7 @@ func (p *SqlitePersistance) GetRemoteUpdates() (err error) { func (p *SqlitePersistance) Push() error { // push changes to remote - - host := p.State.RemoteHostname - if host == "" { + if p.State.RemoteURL == nil { return nil } updates, err := p.GetUpdates(UpdateRequest{Counter: p.State.RemoteCounter, ProcessID: ReservedProcessID}) @@ -99,7 +102,11 @@ func (p *SqlitePersistance) Push() error { panic(err) } - resp, err := http.DefaultClient.Post(host+"/push", "application/json", bytes.NewReader(payload)) + push, err := p.State.RemoteURL.Parse("push") + if err != nil { + panic(err) + } + resp, err := http.DefaultClient.Post(push.String(), "application/json", bytes.NewReader(payload)) if err != nil || resp.StatusCode != 200 { return fmt.Errorf("Error posting update to server: %v", err) } else { @@ -173,7 +180,7 @@ func NewSqlitePersistance(path string) (*SqlitePersistance, error) { } else { // init DB _, err := db.Exec(` - create table if not exists entries (key, value, timestamp, pid, counter, urltoken); + create table if not exists entries (key, value, timestamp, pid, counter, urltoken); create table if not exists state (state);`) if err != nil {