1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-29 01:12:24 +08:00

feat(api): allow multiple API/Gateway addresses

License: MIT
Signed-off-by: Overbool <overbool.xu@gmail.com>
This commit is contained in:
Overbool
2018-09-27 16:25:22 +08:00
committed by Kevin Atkinson
parent fc2575740e
commit 4d5da710c2

View File

@ -412,11 +412,17 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
return nil, fmt.Errorf("serveHTTPApi: GetConfig() failed: %s", err) return nil, fmt.Errorf("serveHTTPApi: GetConfig() failed: %s", err)
} }
apiAddrs := make([]string, 0, 2)
apiAddr, _ := req.Options[commands.ApiOption].(string) apiAddr, _ := req.Options[commands.ApiOption].(string)
if apiAddr == "" { if apiAddr == "" {
apiAddr = cfg.Addresses.API[0] apiAddrs = cfg.Addresses.API
} else {
apiAddrs = append(apiAddrs, apiAddr)
} }
apiMaddr, err := ma.NewMultiaddr(apiAddr)
listeners := make([]manet.Listener, 0, len(apiAddrs))
for _, addr := range apiAddrs {
apiMaddr, err := ma.NewMultiaddr(addr)
if err != nil { if err != nil {
return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err) return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
} }
@ -425,10 +431,14 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
if err != nil { if err != nil {
return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err) return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
} }
// we might have listened to /tcp/0 - lets see what we are listing on // we might have listened to /tcp/0 - lets see what we are listing on
apiMaddr = apiLis.Multiaddr() apiMaddr = apiLis.Multiaddr()
fmt.Printf("API server listening on %s\n", apiMaddr) fmt.Printf("API server listening on %s\n", apiMaddr)
listeners = append(listeners, apiLis)
}
// by default, we don't let you load arbitrary ipfs objects through the api, // by default, we don't let you load arbitrary ipfs objects through the api,
// because this would open up the api to scripting vulnerabilities. // because this would open up the api to scripting vulnerabilities.
// only the webui objects are allowed. // only the webui objects are allowed.
@ -462,15 +472,25 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err) return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err)
} }
if err := node.Repo.SetAPIAddr(apiMaddr); err != nil { if err := node.Repo.SetAPIAddr(listeners[0].Multiaddr()); err != nil {
return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %s", err) return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %s", err)
} }
errc := make(chan error) errc := make(chan error)
var wg sync.WaitGroup
for _, apiLis := range listeners {
wg.Add(1)
go func(lis manet.Listener) {
defer wg.Done()
errc <- corehttp.Serve(node, manet.NetListener(lis), opts...)
}(apiLis)
}
go func() { go func() {
errc <- corehttp.Serve(node, manet.NetListener(apiLis), opts...) wg.Wait()
close(errc) close(errc)
}() }()
return errc, nil return errc, nil
} }
@ -512,16 +532,19 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
return nil, fmt.Errorf("serveHTTPGateway: GetConfig() failed: %s", err) return nil, fmt.Errorf("serveHTTPGateway: GetConfig() failed: %s", err)
} }
gatewayMaddr, err := ma.NewMultiaddr(cfg.Addresses.Gateway[0])
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", cfg.Addresses.Gateway, err)
}
writable, writableOptionFound := req.Options[writableKwd].(bool) writable, writableOptionFound := req.Options[writableKwd].(bool)
if !writableOptionFound { if !writableOptionFound {
writable = cfg.Gateway.Writable writable = cfg.Gateway.Writable
} }
gatewayAddrs := cfg.Addresses.Gateway
listeners := make([]manet.Listener, 0, len(gatewayAddrs))
for _, addr := range gatewayAddrs {
gatewayMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", addr, err)
}
gwLis, err := manet.Listen(gatewayMaddr) gwLis, err := manet.Listen(gatewayMaddr)
if err != nil { if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err) return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
@ -535,6 +558,9 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr) fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
} }
listeners = append(listeners, gwLis)
}
var opts = []corehttp.ServeOption{ var opts = []corehttp.ServeOption{
corehttp.MetricsCollectionOption("gateway"), corehttp.MetricsCollectionOption("gateway"),
corehttp.IPNSHostnameOption(), corehttp.IPNSHostnameOption(),
@ -554,10 +580,20 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
} }
errc := make(chan error) errc := make(chan error)
var wg sync.WaitGroup
for _, lis := range listeners {
wg.Add(1)
go func(lis manet.Listener) {
defer wg.Done()
errc <- corehttp.Serve(node, manet.NetListener(lis), opts...)
}(lis)
}
go func() { go func() {
errc <- corehttp.Serve(node, manet.NetListener(gwLis), opts...) wg.Wait()
close(errc) close(errc)
}() }()
return errc, nil return errc, nil
} }