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  }