@cryptotaxi247 / kubo / commits / 4d5da710c

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