From 3d40f75c91f35dfcd7995e2bf03daaf255833e99 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 25 Sep 2019 18:41:32 -0700 Subject: [PATCH] daemon: support unix domain sockets for the API/gateway All the work was client-side. Unix domain socket multiaddrs already worked server-side. fixes #4218 --- cmd/ipfs/main.go | 30 ++++++++++++---- docs/config.md | 16 +++++++++ go.sum | 8 ++--- test/dependencies/pollEndpoint/main.go | 50 +++++--------------------- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index 8ae51e72adf..ccb914ef9fb 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -6,6 +6,8 @@ import ( "errors" "fmt" "math/rand" + "net" + "net/http" "os" "runtime/pprof" "strings" @@ -22,7 +24,7 @@ import ( "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" - "github.com/ipfs/go-ipfs-cmds/http" + cmdhttp "github.com/ipfs/go-ipfs-cmds/http" "github.com/ipfs/go-ipfs-config" u "github.com/ipfs/go-ipfs-util" logging "github.com/ipfs/go-log" @@ -249,23 +251,39 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { if err != nil { return nil, err } - _, host, err := manet.DialArgs(apiAddr) + network, host, err := manet.DialArgs(apiAddr) if err != nil { return nil, err } // Construct the executor. - opts := []http.ClientOpt{ - http.ClientWithAPIPrefix(corehttp.APIPath), + opts := []cmdhttp.ClientOpt{ + cmdhttp.ClientWithAPIPrefix(corehttp.APIPath), } // Fallback on a local executor if we (a) have a repo and (b) aren't // forcing a daemon. if !daemonRequested && fsrepo.IsInitialized(cctx.ConfigRoot) { - opts = append(opts, http.ClientWithFallback(exe)) + opts = append(opts, cmdhttp.ClientWithFallback(exe)) + } + + switch network { + case "tcp", "tcp4", "tcp6": + case "unix": + path := host + host = "unix" + opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", path) + }, + }, + })) + default: + return nil, fmt.Errorf("unsupported API address: %s", apiAddr) } - return http.NewClient(host, opts...), nil + return cmdhttp.NewClient(host, opts...), nil } // commandDetails returns a command's details for the command given by |path|. diff --git a/docs/config.md b/docs/config.md index 883a650b038..42bcf58d0e5 100644 --- a/docs/config.md +++ b/docs/config.md @@ -77,16 +77,32 @@ Contains information about various listener addresses to be used by this node. - `API` Multiaddr or array of multiaddrs describing the address to serve the local HTTP API on. +Supported Transports: + +* tcp/ip{4,6} - `/ipN/.../tcp/...` +* unix - `/unix/path/to/socket` + Default: `/ip4/127.0.0.1/tcp/5001` - `Gateway` Multiaddr or array of multiaddrs describing the address to serve the local gateway on. +Supported Transports: + +* tcp/ip{4,6} - `/ipN/.../tcp/...` +* unix - `/unix/path/to/socket` + Default: `/ip4/127.0.0.1/tcp/8080` - `Swarm` Array of multiaddrs describing which addresses to listen on for p2p swarm connections. +Supported Transports: + +* tcp/ip{4,6} - `/ipN/.../tcp/...` +* websocket - `/ipN/.../tcp/.../ws` +* quic - `/ipN/.../udp/.../quic` + Default: ```json [ diff --git a/go.sum b/go.sum index 41e5960ff9f..c999c92f0ac 100644 --- a/go.sum +++ b/go.sum @@ -183,8 +183,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IW github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= -github.com/ipfs/go-ipfs-cmds v0.1.0 h1:0CEde9EcxByej8+L6d1PST57J4ambRPyCTjLG5Ymou8= -github.com/ipfs/go-ipfs-cmds v0.1.0/go.mod h1:TiK4e7/V31tuEb8YWDF8lN3qrnDH+BS7ZqWIeYJlAs8= +github.com/ipfs/go-ipfs-cmds v0.1.1 h1:H9/BLf5rcsULHMj/x8gC0e5o+raYhqk1OQsfzbGMNM4= +github.com/ipfs/go-ipfs-cmds v0.1.1/go.mod h1:k1zMXcOLtljA9iAnZHddbH69yVm5+weRL0snmMD/rK0= github.com/ipfs/go-ipfs-config v0.0.11 h1:5/4nas2CQXiKr2/MLxU24GDGTBvtstQIQezuk7ltOQQ= github.com/ipfs/go-ipfs-config v0.0.11/go.mod h1:wveA8UT5ywN26oKStByzmz1CO6cXwLKKM6Jn/Hfw08I= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -596,8 +596,8 @@ github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/test/dependencies/pollEndpoint/main.go b/test/dependencies/pollEndpoint/main.go index 67a5e2be0d5..7eadcd3f702 100644 --- a/test/dependencies/pollEndpoint/main.go +++ b/test/dependencies/pollEndpoint/main.go @@ -3,10 +3,6 @@ package main import ( "flag" - "fmt" - "io/ioutil" - "net/http" - "net/url" "os" "time" @@ -16,11 +12,10 @@ import ( ) var ( - host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on") - endpoint = flag.String("ep", "/version", "which http endpoint path to hit") - tries = flag.Int("tries", 10, "how many tries to make before failing") - timeout = flag.Duration("tout", time.Second, "how long to wait between attempts") - verbose = flag.Bool("v", false, "verbose logging") + host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on") + tries = flag.Int("tries", 10, "how many tries to make before failing") + timeout = flag.Duration("tout", time.Second, "how long to wait between attempts") + verbose = flag.Bool("v", false, "verbose logging") ) var log = logging.Logger("pollEndpoint") @@ -33,37 +28,23 @@ func main() { if err != nil { log.Fatal("NewMultiaddr() failed: ", err) } - p := addr.Protocols() - if len(p) < 2 { - log.Fatal("need two protocols in host flag (/ip/tcp): ", addr) - } - _, host, err := manet.DialArgs(addr) - if err != nil { - log.Fatal("manet.DialArgs() failed: ", err) - } if *verbose { // lower log level logging.SetDebugLogging() } - // construct url to dial - var u url.URL - u.Scheme = "http" - u.Host = host - u.Path = *endpoint - // show what we got start := time.Now() - log.Debugf("starting at %s, tries: %d, timeout: %s, url: %s", start, *tries, *timeout, u) + log.Debugf("starting at %s, tries: %d, timeout: %s, addr: %s", start, *tries, *timeout, addr) for *tries > 0 { - - err := checkOK(http.Get(u.String())) + c, err := manet.Dial(addr) if err == nil { log.Debugf("ok - endpoint reachable with %d tries remaining, took %s", *tries, time.Since(start)) + c.Close() os.Exit(0) } - log.Debug("get failed: ", err) + log.Debug("connect failed: ", err) time.Sleep(*timeout) *tries-- } @@ -71,18 +52,3 @@ func main() { log.Error("failed.") os.Exit(1) } - -func checkOK(resp *http.Response, err error) error { - if err == nil { // request worked - defer resp.Body.Close() - if resp.StatusCode == http.StatusOK { - return nil - } - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - fmt.Fprintf(os.Stderr, "pollEndpoint: ioutil.ReadAll() Error: %s", err) - } - return fmt.Errorf("response not OK. %d %s %q", resp.StatusCode, resp.Status, string(body)) - } - return err -}