@@ -34,13 +34,17 @@ import (
34
34
osh "gx/ipfs/QmXuBJ7DR6k3rmUEKtvVMhwjmXDuJgXXPUt4LQXKBMsU93/go-os-helper"
35
35
ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr"
36
36
loggables "gx/ipfs/QmZ4zF1mBrt8C2mSCM4ZYE4aAnv78f7GvrzufJC4G5tecK/go-libp2p-loggables"
37
+ madns "gx/ipfs/QmfXU2MhWoegxHoeMd3A2ytL2P6CY4FfqGWc23LTNWBwZt/go-multiaddr-dns"
37
38
)
38
39
39
40
// log is the command logger
40
41
var log = logging .Logger ("cmd/ipfs" )
41
42
42
43
var errRequestCanceled = errors .New ("request canceled" )
43
44
45
+ // declared as a var for testing purposes
46
+ var dnsResolver = madns .DefaultResolver
47
+
44
48
const (
45
49
EnvEnableProfiling = "IPFS_PROF"
46
50
cpuProfile = "ipfs.cpuprof"
@@ -235,7 +239,7 @@ func commandShouldRunOnDaemon(details cmdDetails, req *cmds.Request, cctx *oldcm
235
239
// did user specify an api to use for this command?
236
240
apiAddrStr , _ := req .Options [corecmds .ApiOption ].(string )
237
241
238
- client , err := getApiClient ( cctx .ConfigRoot , apiAddrStr )
242
+ client , err := getAPIClient ( req . Context , cctx .ConfigRoot , apiAddrStr )
239
243
if err == repo .ErrApiNotRunning {
240
244
if apiAddrStr != "" && req .Command != daemonCmd {
241
245
// if user SPECIFIED an api, and this cmd is not daemon
@@ -403,10 +407,10 @@ If you're sure go-ipfs isn't running, you can just delete it.
403
407
var checkIPFSUnixFmt = "Otherwise check:\n \t ps aux | grep ipfs"
404
408
var checkIPFSWinFmt = "Otherwise check:\n \t tasklist | findstr ipfs"
405
409
406
- // getApiClient checks the repo, and the given options, checking for
410
+ // getAPIClient checks the repo, and the given options, checking for
407
411
// a running API service. if there is one, it returns a client.
408
412
// otherwise, it returns errApiNotRunning, or another error.
409
- func getApiClient ( repoPath , apiAddrStr string ) (http.Client , error ) {
413
+ func getAPIClient ( ctx context. Context , repoPath , apiAddrStr string ) (http.Client , error ) {
410
414
var apiErrorFmt string
411
415
switch {
412
416
case osh .IsUnix ():
@@ -440,14 +444,35 @@ func getApiClient(repoPath, apiAddrStr string) (http.Client, error) {
440
444
if len (addr .Protocols ()) == 0 {
441
445
return nil , fmt .Errorf (apiErrorFmt , repoPath , "multiaddr doesn't provide any protocols" )
442
446
}
443
- return apiClientForAddr (addr )
447
+ return apiClientForAddr (ctx , addr )
444
448
}
445
449
446
- func apiClientForAddr (addr ma.Multiaddr ) (http.Client , error ) {
450
+ func apiClientForAddr (ctx context.Context , addr ma.Multiaddr ) (http.Client , error ) {
451
+ addr , err := resolveAddr (ctx , addr )
452
+ if err != nil {
453
+ return nil , err
454
+ }
455
+
447
456
_ , host , err := manet .DialArgs (addr )
448
457
if err != nil {
449
458
return nil , err
450
459
}
451
460
452
461
return http .NewClient (host , http .ClientWithAPIPrefix (corehttp .APIPath )), nil
453
462
}
463
+
464
+ func resolveAddr (ctx context.Context , addr ma.Multiaddr ) (ma.Multiaddr , error ) {
465
+ ctx , cancelFunc := context .WithTimeout (ctx , 10 * time .Second )
466
+ defer cancelFunc ()
467
+
468
+ addrs , err := dnsResolver .Resolve (ctx , addr )
469
+ if err != nil {
470
+ return nil , err
471
+ }
472
+
473
+ if len (addrs ) == 0 {
474
+ return nil , errors .New ("non-resolvable API endpoint" )
475
+ }
476
+
477
+ return addrs [0 ], nil
478
+ }
0 commit comments