File: metadata.go

package info (click to toggle)
golang-github-grpc-ecosystem-go-grpc-middleware 2.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,464 kB
  • sloc: makefile: 107; sh: 9
file content (126 lines) | stat: -rw-r--r-- 3,373 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) The go-grpc-middleware Authors.
// Licensed under the Apache License 2.0.

package metadata

import (
	"context"
	"strings"

	grpcMetadata "google.golang.org/grpc/metadata"
)

// MD is a convenience wrapper defining extra functions on the metadata.
type MD grpcMetadata.MD

// ExtractIncoming extracts an inbound metadata from the server-side context.
//
// This function always returns a MD wrapper of the grpcMetadata.MD, in case the context doesn't have metadata it returns
// a new empty MD.
func ExtractIncoming(ctx context.Context) MD {
	md, ok := grpcMetadata.FromIncomingContext(ctx)
	if !ok {
		return MD(grpcMetadata.Pairs())
	}
	return MD(md)
}

// ExtractOutgoing extracts an outbound metadata from the client-side context.
//
// This function always returns a MD wrapper of the grpcMetadata.MD, in case the context doesn't have metadata it returns
// a new empty MD.
func ExtractOutgoing(ctx context.Context) MD {
	md, ok := grpcMetadata.FromOutgoingContext(ctx)
	if !ok {
		return MD(grpcMetadata.Pairs())
	}
	return MD(md)
}

// Clone performs a *deep* copy of the grpcMetadata.MD.
//
// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
// all keys get copied.
func (m MD) Clone(copiedKeys ...string) MD {
	newMd := MD(grpcMetadata.Pairs())
	for k, vv := range m {
		found := false
		if len(copiedKeys) == 0 {
			found = true
		} else {
			for _, allowedKey := range copiedKeys {
				if strings.EqualFold(allowedKey, k) {
					found = true
					break
				}
			}
		}
		if !found {
			continue
		}
		newMd[k] = make([]string, len(vv))
		copy(newMd[k], vv)
	}
	return newMd
}

// ToOutgoing sets the given MD as a client-side context for dispatching.
func (m MD) ToOutgoing(ctx context.Context) context.Context {
	return grpcMetadata.NewOutgoingContext(ctx, grpcMetadata.MD(m))
}

// ToIncoming sets the given MD as a server-side context for dispatching.
//
// This is mostly useful in ServerInterceptors.
func (m MD) ToIncoming(ctx context.Context) context.Context {
	return grpcMetadata.NewIncomingContext(ctx, grpcMetadata.MD(m))
}

// Get retrieves a single value from the metadata.
//
// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set,
// an empty string is returned.
//
// The function is binary-key safe.
func (m MD) Get(key string) string {
	k, _ := encodeKeyValue(key, "")
	vv, ok := m[k]
	if !ok {
		return ""
	}
	return vv[0]
}

// Del retrieves a single value from the metadata.
//
// It works analogously to http.Header.Del, deleting all values if they exist.
//
// The function is binary-key safe.

func (m MD) Del(key string) MD {
	k, _ := encodeKeyValue(key, "")
	delete(m, k)
	return m
}

// Set sets the given value in a metadata.
//
// It works analogously to http.Header.Set, overwriting all previous metadata values.
//
// The function is binary-key safe.
func (m MD) Set(key string, value string) MD {
	k, v := encodeKeyValue(key, value)
	m[k] = []string{v}
	return m
}

// Add retrieves a single value from the metadata.
//
// It works analogously to http.Header.Add, as it appends to any existing values associated with key.
//
// The function is binary-key safe.
func (m MD) Add(key string, value string) MD {
	k, v := encodeKeyValue(key, value)
	m[k] = append(m[k], v)
	return m
}