github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/registry/consul/encoding.go (about) 1 package consul 2 3 import ( 4 "bytes" 5 "compress/zlib" 6 "encoding/hex" 7 "encoding/json" 8 "io/ioutil" 9 10 "github.com/volts-dev/volts/registry" 11 ) 12 13 func encode(buf []byte) string { 14 var b bytes.Buffer 15 defer b.Reset() 16 17 w := zlib.NewWriter(&b) 18 if _, err := w.Write(buf); err != nil { 19 return "" 20 } 21 w.Close() 22 23 return hex.EncodeToString(b.Bytes()) 24 } 25 26 func decode(d string) []byte { 27 hr, err := hex.DecodeString(d) 28 if err != nil { 29 return nil 30 } 31 32 br := bytes.NewReader(hr) 33 zr, err := zlib.NewReader(br) 34 if err != nil { 35 return nil 36 } 37 38 rbuf, err := ioutil.ReadAll(zr) 39 if err != nil { 40 return nil 41 } 42 zr.Close() 43 44 return rbuf 45 } 46 47 func encodeEndpoints(en []*registry.Endpoint) []string { 48 var tags []string 49 for _, e := range en { 50 if b, err := json.Marshal(e); err == nil { 51 tags = append(tags, "e-"+encode(b)) 52 } 53 } 54 return tags 55 } 56 57 func decodeEndpoints(tags []string) []*registry.Endpoint { 58 var en []*registry.Endpoint 59 60 // use the first format you find 61 var ver byte 62 63 for _, tag := range tags { 64 if len(tag) == 0 || tag[0] != 'e' { 65 continue 66 } 67 68 // check version 69 if ver > 0 && tag[1] != ver { 70 continue 71 } 72 73 var e *registry.Endpoint 74 var buf []byte 75 76 // Old encoding was plain 77 if tag[1] == '=' { 78 buf = []byte(tag[2:]) 79 } 80 81 // New encoding is hex 82 if tag[1] == '-' { 83 buf = decode(tag[2:]) 84 } 85 86 if err := json.Unmarshal(buf, &e); err == nil { 87 en = append(en, e) 88 } 89 90 // set version 91 ver = tag[1] 92 } 93 return en 94 } 95 96 func encodeMetadata(md map[string]string) []string { 97 var tags []string 98 for k, v := range md { 99 if b, err := json.Marshal(map[string]string{ 100 k: v, 101 }); err == nil { 102 // new encoding 103 tags = append(tags, "t-"+encode(b)) 104 } 105 } 106 return tags 107 } 108 109 func decodeMetadata(tags []string) map[string]string { 110 md := make(map[string]string) 111 112 var ver byte 113 114 for _, tag := range tags { 115 if len(tag) == 0 || tag[0] != 't' { 116 continue 117 } 118 119 // check version 120 if ver > 0 && tag[1] != ver { 121 continue 122 } 123 124 var kv map[string]string 125 var buf []byte 126 127 // Old encoding was plain 128 if tag[1] == '=' { 129 buf = []byte(tag[2:]) 130 } 131 132 // New encoding is hex 133 if tag[1] == '-' { 134 buf = decode(tag[2:]) 135 } 136 137 // Now unmarshal 138 if err := json.Unmarshal(buf, &kv); err == nil { 139 for k, v := range kv { 140 md[k] = v 141 } 142 } 143 144 // set version 145 ver = tag[1] 146 } 147 return md 148 } 149 150 func encodeVersion(v string) []string { 151 return []string{"v-" + encode([]byte(v))} 152 } 153 154 func decodeVersion(tags []string) (string, bool) { 155 for _, tag := range tags { 156 if len(tag) < 2 || tag[0] != 'v' { 157 continue 158 } 159 160 // Old encoding was plain 161 if tag[1] == '=' { 162 return tag[2:], true 163 } 164 165 // New encoding is hex 166 if tag[1] == '-' { 167 return string(decode(tag[2:])), true 168 } 169 } 170 return "", false 171 }