@cryptotaxi247 / kubo / commits / 012397111

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 }