github.com/gobitfly/go-ethereum@v1.8.12/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/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/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 // Parse parses rawuri into a URI struct, where rawuri is expected to have one 57 // of the following formats: 58 // 59 // * <scheme>:/ 60 // * <scheme>:/<addr> 61 // * <scheme>:/<addr>/<path> 62 // * <scheme>:// 63 // * <scheme>://<addr> 64 // * <scheme>://<addr>/<path> 65 // 66 // with scheme one of bzz, bzz-raw, bzz-immutable, bzz-list or bzz-hash 67 func Parse(rawuri string) (*URI, error) { 68 u, err := url.Parse(rawuri) 69 if err != nil { 70 return nil, err 71 } 72 uri := &URI{Scheme: u.Scheme} 73 74 // check the scheme is valid 75 switch uri.Scheme { 76 case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzz-resource": 77 default: 78 return nil, fmt.Errorf("unknown scheme %q", u.Scheme) 79 } 80 81 // handle URIs like bzz://<addr>/<path> where the addr and path 82 // have already been split by url.Parse 83 if u.Host != "" { 84 uri.Addr = u.Host 85 uri.Path = strings.TrimLeft(u.Path, "/") 86 return uri, nil 87 } 88 89 // URI is like bzz:/<addr>/<path> so split the addr and path from 90 // the raw path (which will be /<addr>/<path>) 91 parts := strings.SplitN(strings.TrimLeft(u.Path, "/"), "/", 2) 92 uri.Addr = parts[0] 93 if len(parts) == 2 { 94 uri.Path = parts[1] 95 } 96 return uri, nil 97 } 98 func (u *URI) Resource() bool { 99 return u.Scheme == "bzz-resource" 100 } 101 102 func (u *URI) Raw() bool { 103 return u.Scheme == "bzz-raw" 104 } 105 106 func (u *URI) Immutable() bool { 107 return u.Scheme == "bzz-immutable" 108 } 109 110 func (u *URI) List() bool { 111 return u.Scheme == "bzz-list" 112 } 113 114 func (u *URI) Hash() bool { 115 return u.Scheme == "bzz-hash" 116 } 117 118 func (u *URI) String() string { 119 return u.Scheme + ":/" + u.Addr + "/" + u.Path 120 } 121 122 func (u *URI) Address() storage.Address { 123 if u.addr != nil { 124 return u.addr 125 } 126 if hashMatcher.MatchString(u.Addr) { 127 u.addr = common.Hex2Bytes(u.Addr) 128 return u.addr 129 } 130 return nil 131 }