Move api version check to header
License: MIT Signed-off-by: rht <rhtbot@gmail.com>
rht committed
Dec 4, 2015 at 10:07 UTC
0123971118b5788cdf6715f6800c0c6d159fe97e
3 files changed
+37
-68
cmd/ipfs/main.go
+5
-65
@@ -416,17 +416,13 @@ func commandShouldRunOnDaemon(details cmdDetails, req cmds.Request, root *cmds.C
416
return nil, err
417
}
418
419
- if client != nil { // daemon is running
419
+ if client != nil { // api file exists
420
if details.cannotRunOnDaemon {
421
- e := "cannot use API with this command."
422
-
421
// check if daemon locked. legacy error text, for now.
424
- daemonLocked, _ := fsrepo.LockedByOtherProcess(req.InvocContext().ConfigRoot)
425
- if daemonLocked {
426
- e = "ipfs daemon is running. please stop it to run this command"
422
+ if daemonLocked, _ := fsrepo.LockedByOtherProcess(req.InvocContext().ConfigRoot); daemonLocked {
423
+ return nil, cmds.ClientError("ipfs daemon is running. please stop it to run this command")
424
}
428
-
429
- return nil, cmds.ClientError(e)
425
+ return nil, nil
426
}
427
428
return client, nil
@@ -604,63 +600,7 @@ func getApiClient(repoPath, apiAddrStr string) (cmdsHttp.Client, error) {
600
return nil, err
601
}
602
607
- client, err := apiClientForAddr(addr)
608
- if err != nil {
609
- return nil, err
610
- }
611
-
612
- // make sure the api is actually running.
613
- // this is slow, as it might mean an RTT to a remote server.
614
- // TODO: optimize some way
615
- if err := apiVersionMatches(client); err != nil {
616
- return nil, err
617
- }
618
-
619
- return client, nil
620
-}
621
-
622
-// apiVersionMatches checks whether the api server is running the
623
-// same version of go-ipfs. for now, only the exact same version of
624
-// client + server work. In the future, we should use semver for
625
-// proper API versioning! \o/
626
-func apiVersionMatches(client cmdsHttp.Client) (err error) {
627
- ver, err := doVersionRequest(client)
628
- if err != nil {
629
- return err
630
- }
631
-
632
- currv := config.CurrentVersionNumber
633
- if ver.Version != currv {
634
- return fmt.Errorf("%s (%s != %s)", errApiVersionMismatch, ver.Version, currv)
635
- }
636
- return nil
637
-}
638
-
639
-func doVersionRequest(client cmdsHttp.Client) (*coreCmds.VersionOutput, error) {
640
- cmd := coreCmds.VersionCmd
641
- optDefs, err := cmd.GetOptions([]string{})
642
- if err != nil {
643
- return nil, err
644
- }
645
-
646
- req, err := cmds.NewRequest([]string{"version"}, nil, nil, nil, cmd, optDefs)
647
- if err != nil {
648
- return nil, err
649
- }
650
-
651
- res, err := client.Send(req)
652
- if err != nil {
653
- if isConnRefused(err) {
654
- err = repo.ErrApiNotRunning
655
- }
656
- return nil, err
657
- }
658
-
659
- ver, ok := res.Output().(*coreCmds.VersionOutput)
660
- if !ok {
661
- return nil, errUnexpectedApiOutput
662
- }
663
- return ver, nil
603
+ return apiClientForAddr(addr)
604
}
605
606
func apiClientForAddr(addr ma.Multiaddr) (cmdsHttp.Client, error) {
commands/http/handler.go
+23
-1
@@ -14,6 +14,7 @@ import (
14
15
cors "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors"
16
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
17
+ "github.com/ipfs/go-ipfs/repo/config"
18
19
cmds "github.com/ipfs/go-ipfs/commands"
20
logging "github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log"
@@ -35,7 +36,10 @@ type Handler struct {
36
corsHandler http.Handler
37
}
38
38
-var ErrNotFound = errors.New("404 page not found")
39
+var (
40
+ ErrNotFound = errors.New("404 page not found")
41
+ errApiVersionMismatch = errors.New("api version mismatch")
42
+)
43
44
const (
45
StreamErrHeader = "X-Stream-Error"
@@ -423,3 +427,21 @@ func allowReferer(r *http.Request, cfg *ServerConfig) bool {
427
428
return false
429
}
430
+
431
+// apiVersionMatches checks whether the api client is running the
432
+// same version of go-ipfs. for now, only the exact same version of
433
+// client + server work. In the future, we should use semver for
434
+// proper API versioning! \o/
435
+func apiVersionMatches(r *http.Request) error {
436
+ clientVersion := r.UserAgent()
437
+ // skips check if client is not go-ipfs
438
+ if clientVersion == "" || !strings.Contains(clientVersion, "/go-ipfs/") {
439
+ return nil
440
+ }
441
+
442
+ daemonVersion := fmt.Sprintf("/go-ipfs/%s/", config.CurrentVersionNumber)
443
+ if daemonVersion != clientVersion {
444
+ return fmt.Errorf("%s (%s != %s)", errApiVersionMismatch, daemonVersion, clientVersion)
445
+ }
446
+ return nil
447
+}
commands/http/parse.go
+9
-2
@@ -20,12 +20,20 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
20
21
stringArgs := make([]string, 0)
22
23
+ if err := apiVersionMatches(r); err != nil {
24
+ if path[0] != "version" { // compatibility with previous version check
25
+ return nil, err
26
+ }
27
+ }
28
+
29
cmd, err := root.Get(path[:len(path)-1])
30
if err != nil {
31
// 404 if there is no command at that path
32
return nil, ErrNotFound
33
28
- } else if sub := cmd.Subcommand(path[len(path)-1]); sub == nil {
34
+ }
35
+
36
+ if sub := cmd.Subcommand(path[len(path)-1]); sub == nil {
37
if len(path) <= 1 {
38
return nil, ErrNotFound
39
}
@@ -34,7 +42,6 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
42
// e.g. /objects/Qabc12345 (we are passing "Qabc12345" to the "objects" command)
43
stringArgs = append(stringArgs, path[len(path)-1])
44
path = path[:len(path)-1]
37
-
45
} else {
46
cmd = sub
47
}