feat(api): allow multiple API/Gateway addresses
License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>
Overbool committed
Sep 27, 2018 at 16:25 UTC
4d5da710c2458e7935503c0dbc71d7d15c58512e
1 file changed
+65
-29
cmd/ipfs/daemon.go
+65
-29
@@ -412,22 +412,32 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
412
return nil, fmt.Errorf("serveHTTPApi: GetConfig() failed: %s", err)
413
}
414
415
+ apiAddrs := make([]string, 0, 2)
416
apiAddr, _ := req.Options[commands.ApiOption].(string)
417
if apiAddr == "" {
417
- apiAddr = cfg.Addresses.API[0]
418
- }
419
- apiMaddr, err := ma.NewMultiaddr(apiAddr)
420
- if err != nil {
421
- return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
418
+ apiAddrs = cfg.Addresses.API
419
+ } else {
420
+ apiAddrs = append(apiAddrs, apiAddr)
421
}
422
424
- apiLis, err := manet.Listen(apiMaddr)
425
- if err != nil {
426
- return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
423
+ listeners := make([]manet.Listener, 0, len(apiAddrs))
424
+ for _, addr := range apiAddrs {
425
+ apiMaddr, err := ma.NewMultiaddr(addr)
426
+ if err != nil {
427
+ return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
428
+ }
429
+
430
+ apiLis, err := manet.Listen(apiMaddr)
431
+ if err != nil {
432
+ return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
433
+ }
434
+
435
+ // we might have listened to /tcp/0 - lets see what we are listing on
436
+ apiMaddr = apiLis.Multiaddr()
437
+ fmt.Printf("API server listening on %s\n", apiMaddr)
438
+
439
+ listeners = append(listeners, apiLis)
440
}
428
- // we might have listened to /tcp/0 - lets see what we are listing on
429
- apiMaddr = apiLis.Multiaddr()
430
- fmt.Printf("API server listening on %s\n", apiMaddr)
441
442
// by default, we don't let you load arbitrary ipfs objects through the api,
443
// because this would open up the api to scripting vulnerabilities.
@@ -462,15 +472,25 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
472
return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err)
473
}
474
465
- if err := node.Repo.SetAPIAddr(apiMaddr); err != nil {
475
+ if err := node.Repo.SetAPIAddr(listeners[0].Multiaddr()); err != nil {
476
return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %s", err)
477
}
478
479
errc := make(chan error)
480
+ var wg sync.WaitGroup
481
+ for _, apiLis := range listeners {
482
+ wg.Add(1)
483
+ go func(lis manet.Listener) {
484
+ defer wg.Done()
485
+ errc <- corehttp.Serve(node, manet.NetListener(lis), opts...)
486
+ }(apiLis)
487
+ }
488
+
489
go func() {
471
- errc <- corehttp.Serve(node, manet.NetListener(apiLis), opts...)
490
+ wg.Wait()
491
close(errc)
492
}()
493
+
494
return errc, nil
495
}
496
@@ -512,27 +532,33 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
532
return nil, fmt.Errorf("serveHTTPGateway: GetConfig() failed: %s", err)
533
}
534
515
- gatewayMaddr, err := ma.NewMultiaddr(cfg.Addresses.Gateway[0])
516
- if err != nil {
517
- return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", cfg.Addresses.Gateway, err)
518
- }
519
-
535
writable, writableOptionFound := req.Options[writableKwd].(bool)
536
if !writableOptionFound {
537
writable = cfg.Gateway.Writable
538
}
539
525
- gwLis, err := manet.Listen(gatewayMaddr)
526
- if err != nil {
527
- return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
528
- }
529
- // we might have listened to /tcp/0 - lets see what we are listing on
530
- gatewayMaddr = gwLis.Multiaddr()
540
+ gatewayAddrs := cfg.Addresses.Gateway
541
+ listeners := make([]manet.Listener, 0, len(gatewayAddrs))
542
+ for _, addr := range gatewayAddrs {
543
+ gatewayMaddr, err := ma.NewMultiaddr(addr)
544
+ if err != nil {
545
+ return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", addr, err)
546
+ }
547
532
- if writable {
533
- fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
534
- } else {
535
- fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
548
+ gwLis, err := manet.Listen(gatewayMaddr)
549
+ if err != nil {
550
+ return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
551
+ }
552
+ // we might have listened to /tcp/0 - lets see what we are listing on
553
+ gatewayMaddr = gwLis.Multiaddr()
554
+
555
+ if writable {
556
+ fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
557
+ } else {
558
+ fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
559
+ }
560
+
561
+ listeners = append(listeners, gwLis)
562
}
563
564
var opts = []corehttp.ServeOption{
@@ -554,10 +580,20 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
580
}
581
582
errc := make(chan error)
583
+ var wg sync.WaitGroup
584
+ for _, lis := range listeners {
585
+ wg.Add(1)
586
+ go func(lis manet.Listener) {
587
+ defer wg.Done()
588
+ errc <- corehttp.Serve(node, manet.NetListener(lis), opts...)
589
+ }(lis)
590
+ }
591
+
592
go func() {
558
- errc <- corehttp.Serve(node, manet.NetListener(gwLis), opts...)
593
+ wg.Wait()
594
close(errc)
595
}()
596
+
597
return errc, nil
598
}
599