@cryptotaxi247 / kubo / commits / 6f9c297f0

update multiaddr for ipfs addrs

Juan Batiz-Benet committed Jan 20, 2015 at 12:29 UTC 6f9c297f0876d883f102e4fe09c60c61d5712d36
7 files changed +116 -41
Godeps/Godeps.json
+2 -2
@@ -167,8 +167,8 @@
167 },
168 {
169 "ImportPath": "github.com/jbenet/go-multiaddr",
170 - "Comment": "0.1.2-34-g0d7b54b",
171 - "Rev": "0d7b54ba432fda14bac37cdad717bd6270eacc85"
170 + "Comment": "0.1.2-38-gc13f11b",
171 + "Rev": "c13f11bbfe6439771f4df7bfb330f686826144e8"
172 },
173 {
174 "ImportPath": "github.com/jbenet/go-multiaddr-net",
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/.travis.yml
+1 -2
@@ -1,10 +1,9 @@
1 language: go
2
3 go:
4 - - 1.2
4 - 1.3
5 - release
6 - tip
7
8 script:
10 - - go test -v ./...
9 + - go test -race -cpu=5 -v ./...
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go
+77 -23
@@ -2,10 +2,13 @@ package multiaddr
2
3 import (
4 "encoding/binary"
5 + "errors"
6 "fmt"
7 "net"
8 "strconv"
9 "strings"
10 +
11 + mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
12 )
13
14 func stringToBytes(s string) ([]byte, error) {
@@ -31,17 +34,19 @@ func stringToBytes(s string) ([]byte, error) {
34 b = append(b, CodeToVarint(p.Code)...)
35 sp = sp[1:]
36
34 - if p.Size > 0 {
35 - if len(sp) < 1 {
36 - return nil, fmt.Errorf("protocol requires address, none given: %s", p.Name)
37 - }
38 - a, err := addressStringToBytes(p, sp[0])
39 - if err != nil {
40 - return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err)
41 - }
42 - b = append(b, a...)
43 - sp = sp[1:]
37 + if p.Size == 0 { // no length.
38 + continue
39 + }
40 +
41 + if len(sp) < 1 {
42 + return nil, fmt.Errorf("protocol requires address, none given: %s", p.Name)
43 + }
44 + a, err := addressStringToBytes(p, sp[0])
45 + if err != nil {
46 + return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err)
47 }
48 + b = append(b, a...)
49 + sp = sp[1:]
50 }
51 return b, nil
52 }
@@ -51,7 +56,14 @@ func bytesToString(b []byte) (ret string, err error) {
56 defer func() {
57 if e := recover(); e != nil {
58 ret = ""
54 - err = e.(error)
59 + switch e := e.(type) {
60 + case error:
61 + err = e
62 + case string:
63 + err = errors.New(e)
64 + default:
65 + err = fmt.Errorf("%v", e)
66 + }
67 }
68 }()
69
@@ -65,20 +77,38 @@ func bytesToString(b []byte) (ret string, err error) {
77 if p.Code == 0 {
78 return "", fmt.Errorf("no protocol with code %d", code)
79 }
68 - s = strings.Join([]string{s, "/", p.Name}, "")
80 + s += "/" + p.Name
81
70 - if p.Size > 0 {
71 - a := addressBytesToString(p, b[:(p.Size/8)])
72 - if len(a) > 0 {
73 - s = strings.Join([]string{s, "/", a}, "")
74 - }
75 - b = b[(p.Size / 8):]
82 + if p.Size == 0 {
83 + continue
84 + }
85 +
86 + size := sizeForAddr(p, b)
87 + a, err := addressBytesToString(p, b[:size])
88 + if err != nil {
89 + return "", err
90 }
91 + if len(a) > 0 {
92 + s += "/" + a
93 + }
94 + b = b[size:]
95 }
96
97 return s, nil
98 }
99
100 +func sizeForAddr(p Protocol, b []byte) int {
101 + switch {
102 + case p.Size > 0:
103 + return (p.Size / 8)
104 + case p.Size == 0:
105 + return 0
106 + default:
107 + size, n := ReadVarintCode(b)
108 + return size + n
109 + }
110 +}
111 +
112 func bytesSplit(b []byte) (ret [][]byte, err error) {
113 // panic handler, in case we try accessing bytes incorrectly.
114 defer func() {
@@ -96,7 +126,8 @@ func bytesSplit(b []byte) (ret [][]byte, err error) {
126 return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0])
127 }
128
99 - length := n + (p.Size / 8)
129 + size := sizeForAddr(p, b[n:])
130 + length := n + size
131 ret = append(ret, b[:length])
132 b = b[length:]
133 }
@@ -133,23 +164,46 @@ func addressStringToBytes(p Protocol, s string) ([]byte, error) {
164 b := make([]byte, 2)
165 binary.BigEndian.PutUint16(b, uint16(i))
166 return b, nil
167 +
168 + case P_IPFS: // ipfs
169 + // the address is a varint prefixed multihash string representation
170 + m, err := mh.FromB58String(s)
171 + if err != nil {
172 + return nil, fmt.Errorf("failed to parse ipfs addr: %s %s", s, err)
173 + }
174 + size := CodeToVarint(len(m))
175 + b := append(size, m...)
176 + return b, nil
177 }
178
179 return []byte{}, fmt.Errorf("failed to parse %s addr: unknown", p.Name)
180 }
181
141 -func addressBytesToString(p Protocol, b []byte) string {
182 +func addressBytesToString(p Protocol, b []byte) (string, error) {
183 switch p.Code {
184
185 // ipv4,6
186 case P_IP4, P_IP6:
146 - return net.IP(b).String()
187 + return net.IP(b).String(), nil
188
189 // tcp udp dccp sctp
190 case P_TCP, P_UDP, P_DCCP, P_SCTP:
191 i := binary.BigEndian.Uint16(b)
151 - return strconv.Itoa(int(i))
192 + return strconv.Itoa(int(i)), nil
193 +
194 + case P_IPFS: // ipfs
195 + // the address is a varint-prefixed multihash string representation
196 + size, n := ReadVarintCode(b)
197 + b = b[n:]
198 + if len(b) != size {
199 + panic("inconsistent lengths")
200 + }
201 + m, err := mh.Cast(b)
202 + if err != nil {
203 + return "", err
204 + }
205 + return m.B58String(), nil
206 }
207
154 - return ""
208 + return "", fmt.Errorf("unknown protocol")
209 }
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go
+5 -1
@@ -64,6 +64,7 @@ func (m *multiaddr) Protocols() []Protocol {
64 }
65 }()
66
67 + size := 0
68 ps := []Protocol{}
69 b := m.bytes[:]
70 for len(b) > 0 {
@@ -75,7 +76,10 @@ func (m *multiaddr) Protocols() []Protocol {
76 panic(fmt.Errorf("no protocol with code %d", b[0]))
77 }
78 ps = append(ps, p)
78 - b = b[n+(p.Size/8):]
79 + b = b[n:]
80 +
81 + size = sizeForAddr(p, b)
82 + b = b[size:]
83 }
84 return ps
85 }
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go
+10 -2
@@ -32,11 +32,13 @@ func TestConstructFails(t *testing.T) {
32 "/ip4/127.0.0.1/udp",
33 "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa",
34 "/ip4/127.0.0.1/tcp",
35 + "/ip4/127.0.0.1/ipfs",
36 + "/ip4/127.0.0.1/ipfs/tcp",
37 }
38
39 for _, a := range cases {
40 if _, err := NewMultiaddr(a); err == nil {
39 - t.Errorf("should have failed: %s", a)
41 + t.Errorf("should have failed: %s - %s", a, err)
42 }
43 }
44 }
@@ -55,18 +57,24 @@ func TestConstructSucceeds(t *testing.T) {
57 "/sctp/1234",
58 "/udp/65535",
59 "/tcp/65535",
60 + "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
61 "/udp/1234/sctp/1234",
62 "/udp/1234/udt",
63 "/udp/1234/utp",
64 + "/tcp/1234/http",
65 + "/tcp/1234/https",
66 + "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
67 "/ip4/127.0.0.1/udp/1234",
68 "/ip4/127.0.0.1/udp/0",
69 "/ip4/127.0.0.1/tcp/1234",
70 "/ip4/127.0.0.1/tcp/1234/",
71 + "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
72 + "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
73 }
74
75 for _, a := range cases {
76 if _, err := NewMultiaddr(a); err != nil {
69 - t.Errorf("should have succeeded: %s", a)
77 + t.Errorf("should have succeeded: %s -- %s", a, err)
78 }
79 }
80 }
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.csv
+1
@@ -7,5 +7,6 @@ code size name
7 132 16 sctp
8 301 0 udt
9 302 0 utp
10 +421 V ipfs
11 480 0 http
12 443 0 https
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.go
+20 -11
@@ -9,7 +9,7 @@ import (
9 // Protocol is a Multiaddr protocol description structure.
10 type Protocol struct {
11 Code int
12 - Size int
12 + Size int // a size of -1 indicates a length-prefixed variable size
13 Name string
14 VCode []byte
15 }
@@ -19,14 +19,22 @@ type Protocol struct {
19 // 2. ensuring errors in the csv don't screw up code.
20 // 3. changing a number has to happen in two places.
21 const (
22 - P_IP4 = 4
23 - P_TCP = 6
24 - P_UDP = 17
25 - P_DCCP = 33
26 - P_IP6 = 41
27 - P_SCTP = 132
28 - P_UTP = 301
29 - P_UDT = 302
22 + P_IP4 = 4
23 + P_TCP = 6
24 + P_UDP = 17
25 + P_DCCP = 33
26 + P_IP6 = 41
27 + P_SCTP = 132
28 + P_UTP = 301
29 + P_UDT = 302
30 + P_IPFS = 421
31 + P_HTTP = 480
32 + P_HTTPS = 443
33 +)
34 +
35 +// These are special sizes
36 +const (
37 + LengthPrefixedVarSize = -1
38 )
39
40 // Protocols is the list of multiaddr protocols supported by this module.
@@ -40,8 +48,9 @@ var Protocols = []Protocol{
48 Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)},
49 Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)},
50 Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)},
43 - // {480, 0, "http"},
44 - // {443, 0, "https"},
51 + Protocol{P_HTTP, 0, "http", CodeToVarint(P_HTTP)},
52 + Protocol{P_HTTPS, 0, "https", CodeToVarint(P_HTTPS)},
53 + Protocol{P_IPFS, LengthPrefixedVarSize, "ipfs", CodeToVarint(P_IPFS)},
54 }
55
56 // ProtocolWithName returns the Protocol description with given string name.