github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/util/ipfsaddr/ipfsaddr.go (about) 1 package ipfsaddr 2 3 import ( 4 "errors" 5 "strings" 6 7 ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" 8 9 peer "github.com/ipfs/go-ipfs/p2p/peer" 10 eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog" 11 ) 12 13 var log = eventlog.Logger("ipfsaddr") 14 15 // ErrInvalidAddr signals an address is not a valid ipfs address. 16 var ErrInvalidAddr = errors.New("invalid ipfs address") 17 18 type IPFSAddr interface { 19 ID() peer.ID 20 Multiaddr() ma.Multiaddr 21 Transport() ma.Multiaddr 22 String() string 23 Equal(b interface{}) bool 24 } 25 26 type ipfsAddr struct { 27 ma ma.Multiaddr 28 id peer.ID 29 } 30 31 func (a ipfsAddr) ID() peer.ID { 32 return a.id 33 } 34 35 func (a ipfsAddr) Multiaddr() ma.Multiaddr { 36 return a.ma 37 } 38 39 func (a ipfsAddr) Transport() ma.Multiaddr { 40 return Transport(a) 41 } 42 43 func (a ipfsAddr) String() string { 44 return a.ma.String() 45 } 46 47 func (a ipfsAddr) Equal(b interface{}) bool { 48 if ib, ok := b.(IPFSAddr); ok { 49 return a.Multiaddr().Equal(ib.Multiaddr()) 50 } 51 if mb, ok := b.(ma.Multiaddr); ok { 52 return a.Multiaddr().Equal(mb) 53 } 54 return false 55 } 56 57 // ParseString parses a string representation of an address into an IPFSAddr 58 func ParseString(str string) (a IPFSAddr, err error) { 59 if str == "" { 60 return nil, ErrInvalidAddr 61 } 62 63 m, err := ma.NewMultiaddr(str) 64 if err != nil { 65 return nil, err 66 } 67 68 return ParseMultiaddr(m) 69 } 70 71 // ParseMultiaddr parses a multiaddr into an IPFSAddr 72 func ParseMultiaddr(m ma.Multiaddr) (a IPFSAddr, err error) { 73 // never panic. 74 defer func() { 75 if r := recover(); r != nil { 76 log.Debug("recovered from panic: ", r) 77 a = nil 78 err = ErrInvalidAddr 79 } 80 }() 81 82 if m == nil { 83 return nil, ErrInvalidAddr 84 } 85 86 // make sure it's an ipfs addr 87 parts := ma.Split(m) 88 if len(parts) < 1 { 89 return nil, ErrInvalidAddr 90 } 91 ipfspart := parts[len(parts)-1] // last part 92 if ipfspart.Protocols()[0].Code != ma.P_IPFS { 93 return nil, ErrInvalidAddr 94 } 95 96 // make sure ipfs id parses as a peer.ID 97 peerIdParts := strings.Split(ipfspart.String(), "/") 98 peerIdStr := peerIdParts[len(peerIdParts)-1] 99 id, err := peer.IDB58Decode(peerIdStr) 100 if err != nil { 101 return nil, err 102 } 103 104 return ipfsAddr{ma: m, id: id}, nil 105 } 106 107 func Transport(iaddr IPFSAddr) (maddr ma.Multiaddr) { 108 maddr = iaddr.Multiaddr() 109 split := ma.Split(maddr) 110 maddr = ma.Join(split[:len(split)-1]...) 111 return 112 }