github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/swarm/api/uri.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "fmt" 21 "net/url" 22 "regexp" 23 "strings" 24 25 "github.com/PlatONnetwork/PlatON-Go/common" 26 "github.com/PlatONnetwork/PlatON-Go/swarm/storage" 27 ) 28 29 //matches hex swarm hashes 30 // TODO: this is bad, it should not be hardcoded how long is a hash 31 var hashMatcher = regexp.MustCompile("^([0-9A-Fa-f]{64})([0-9A-Fa-f]{64})?$") 32 33 // URI is a reference to content stored in swarm. 34 type URI struct { 35 // Scheme has one of the following values: 36 // 37 // * bzz - an entry in a swarm manifest 38 // * bzz-raw - raw swarm content 39 // * bzz-immutable - immutable URI of an entry in a swarm manifest 40 // (address is not resolved) 41 // * bzz-list - list of all files contained in a swarm manifest 42 // 43 Scheme string 44 45 // Addr is either a hexadecimal storage address or it an address which 46 // resolves to a storage address 47 Addr string 48 49 // addr stores the parsed storage address 50 addr storage.Address 51 52 // Path is the path to the content within a swarm manifest 53 Path string 54 } 55 56 func (u *URI) MarshalJSON() (out []byte, err error) { 57 return []byte(`"` + u.String() + `"`), nil 58 } 59 60 func (u *URI) UnmarshalJSON(value []byte) error { 61 uri, err := Parse(string(value)) 62 if err != nil { 63 return err 64 } 65 *u = *uri 66 return nil 67 } 68 69 // Parse parses rawuri into a URI struct, where rawuri is expected to have one 70 // of the following formats: 71 // 72 // * <scheme>:/ 73 // * <scheme>:/<addr> 74 // * <scheme>:/<addr>/<path> 75 // * <scheme>:// 76 // * <scheme>://<addr> 77 // * <scheme>://<addr>/<path> 78 // 79 // with scheme one of bzz, bzz-raw, bzz-immutable, bzz-list or bzz-hash 80 func Parse(rawuri string) (*URI, error) { 81 u, err := url.Parse(rawuri) 82 if err != nil { 83 return nil, err 84 } 85 uri := &URI{Scheme: u.Scheme} 86 87 // check the scheme is valid 88 switch uri.Scheme { 89 case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzz-resource": 90 default: 91 return nil, fmt.Errorf("unknown scheme %q", u.Scheme) 92 } 93 94 // handle URIs like bzz://<addr>/<path> where the addr and path 95 // have already been split by url.Parse 96 if u.Host != "" { 97 uri.Addr = u.Host 98 uri.Path = strings.TrimLeft(u.Path, "/") 99 return uri, nil 100 } 101 102 // URI is like bzz:/<addr>/<path> so split the addr and path from 103 // the raw path (which will be /<addr>/<path>) 104 parts := strings.SplitN(strings.TrimLeft(u.Path, "/"), "/", 2) 105 uri.Addr = parts[0] 106 if len(parts) == 2 { 107 uri.Path = parts[1] 108 } 109 return uri, nil 110 } 111 func (u *URI) Resource() bool { 112 return u.Scheme == "bzz-resource" 113 } 114 115 func (u *URI) Raw() bool { 116 return u.Scheme == "bzz-raw" 117 } 118 119 func (u *URI) Immutable() bool { 120 return u.Scheme == "bzz-immutable" 121 } 122 123 func (u *URI) List() bool { 124 return u.Scheme == "bzz-list" 125 } 126 127 func (u *URI) Hash() bool { 128 return u.Scheme == "bzz-hash" 129 } 130 131 func (u *URI) String() string { 132 return u.Scheme + ":/" + u.Addr + "/" + u.Path 133 } 134 135 func (u *URI) Address() storage.Address { 136 if u.addr != nil { 137 return u.addr 138 } 139 if hashMatcher.MatchString(u.Addr) { 140 u.addr = common.Hex2Bytes(u.Addr) 141 return u.addr 142 } 143 return nil 144 }