blob: 3649fb5b888564712133043051628f425445af18 [file] [log] [blame]
Girish Kumardef46fc2020-08-05 18:20:11 +00001// Copyright 2017 Michal Witkowski. All Rights Reserved.
2// See LICENSE for licensing terms.
3
4package grpc_opentracing
5
6import (
7 "encoding/base64"
8 "strings"
9
Girish Kumardef46fc2020-08-05 18:20:11 +000010 "google.golang.org/grpc/metadata"
11)
12
13const (
14 binHdrSuffix = "-bin"
15)
16
17// metadataTextMap extends a metadata.MD to be an opentracing textmap
18type metadataTextMap metadata.MD
19
20// Set is a opentracing.TextMapReader interface that extracts values.
21func (m metadataTextMap) Set(key, val string) {
22 // gRPC allows for complex binary values to be written.
23 encodedKey, encodedVal := encodeKeyValue(key, val)
24 // The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append
25 // we just override.
26 m[encodedKey] = []string{encodedVal}
27}
28
29// ForeachKey is a opentracing.TextMapReader interface that extracts values.
30func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error {
31 for k, vv := range m {
32 for _, v := range vv {
khenaidood948f772021-08-11 17:49:24 -040033 if err := callback(k, v); err != nil {
34 return err
Girish Kumardef46fc2020-08-05 18:20:11 +000035 }
36 }
37 }
38 return nil
39}
40
41// encodeKeyValue encodes key and value qualified for transmission via gRPC.
42// note: copy pasted from private values of grpc.metadata
43func encodeKeyValue(k, v string) (string, string) {
44 k = strings.ToLower(k)
45 if strings.HasSuffix(k, binHdrSuffix) {
46 val := base64.StdEncoding.EncodeToString([]byte(v))
47 v = string(val)
48 }
49 return k, v
50}