gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/go-grpc-middleware/tracing/opentracing/metadata.go (about) 1 // Copyright 2017 Michal Witkowski. All Rights Reserved. 2 // See LICENSE for licensing terms. 3 4 package grpc_opentracing 5 6 import ( 7 "encoding/base64" 8 "strings" 9 10 "fmt" 11 12 "gitee.com/ks-custle/core-gm/grpc/metadata" 13 ) 14 15 const ( 16 binHdrSuffix = "-bin" 17 ) 18 19 // metadataTextMap extends a metadata.MD to be an opentracing textmap 20 type metadataTextMap metadata.MD 21 22 // Set is a opentracing.TextMapReader interface that extracts values. 23 func (m metadataTextMap) Set(key, val string) { 24 // gRPC allows for complex binary values to be written. 25 encodedKey, encodedVal := encodeKeyValue(key, val) 26 // The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append 27 // we just override. 28 m[encodedKey] = []string{encodedVal} 29 } 30 31 // ForeachKey is a opentracing.TextMapReader interface that extracts values. 32 func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error { 33 for k, vv := range m { 34 for _, v := range vv { 35 if decodedKey, decodedVal, err := metadata.DecodeKeyValue(k, v); err == nil { 36 if err = callback(decodedKey, decodedVal); err != nil { 37 return err 38 } 39 } else { 40 return fmt.Errorf("failed decoding opentracing from gRPC metadata: %v", err) 41 } 42 } 43 } 44 return nil 45 } 46 47 // encodeKeyValue encodes key and value qualified for transmission via gRPC. 48 // note: copy pasted from private values of grpc.metadata 49 func encodeKeyValue(k, v string) (string, string) { 50 k = strings.ToLower(k) 51 if strings.HasSuffix(k, binHdrSuffix) { 52 val := base64.StdEncoding.EncodeToString([]byte(v)) 53 v = string(val) 54 } 55 return k, v 56 }