Skip to content

Commit 5829a06

Browse files
authored
Merge pull request #43 from crosbymichael/metadata
metadata as KeyValue type
2 parents d134fe7 + 694de9d commit 5829a06

7 files changed

Lines changed: 71 additions & 39 deletions

File tree

client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int
112112
)
113113

114114
if metadata, ok := GetMetadata(ctx); ok {
115-
creq.Metadata = metadata
115+
metadata.setRequest(creq)
116116
}
117117

118118
if dl, ok := ctx.Deadline(); ok {

example/cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func client() error {
109109
}
110110

111111
ctx := context.Background()
112-
md := ttrpc.Metadata{}
112+
md := ttrpc.MD{}
113113
md.Set("name", "koye")
114114
ctx = ttrpc.WithMetadata(ctx, md)
115115

metadata.go

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,74 @@
1616

1717
package ttrpc
1818

19-
import "context"
19+
import (
20+
"context"
21+
"strings"
22+
)
2023

21-
// Metadata represents the key-value pairs (similar to http.Header) to be passed to ttrpc server from a client.
22-
type Metadata map[string]StringList
24+
// MD is the user type for ttrpc metadata
25+
type MD map[string][]string
2326

2427
// Get returns the metadata for a given key when they exist.
2528
// If there is no metadata, a nil slice and false are returned.
26-
func (m Metadata) Get(key string) ([]string, bool) {
29+
func (m MD) Get(key string) ([]string, bool) {
30+
key = strings.ToLower(key)
2731
list, ok := m[key]
28-
if !ok || len(list.List) == 0 {
32+
if !ok || len(list) == 0 {
2933
return nil, false
3034
}
3135

32-
return list.List, true
36+
return list, true
3337
}
3438

3539
// Set sets the provided values for a given key.
3640
// The values will overwrite any existing values.
3741
// If no values provided, a key will be deleted.
38-
func (m Metadata) Set(key string, values ...string) {
42+
func (m MD) Set(key string, values ...string) {
43+
key = strings.ToLower(key)
3944
if len(values) == 0 {
4045
delete(m, key)
4146
return
4247
}
43-
44-
m[key] = StringList{List: values}
48+
m[key] = values
4549
}
4650

4751
// Append appends additional values to the given key.
48-
func (m Metadata) Append(key string, values ...string) {
52+
func (m MD) Append(key string, values ...string) {
53+
key = strings.ToLower(key)
4954
if len(values) == 0 {
5055
return
5156
}
52-
53-
list, ok := m[key]
57+
current, ok := m[key]
5458
if ok {
55-
m.Set(key, append(list.List, values...)...)
59+
m.Set(key, append(current, values...)...)
5660
} else {
5761
m.Set(key, values...)
5862
}
5963
}
6064

65+
func (m MD) setRequest(r *Request) {
66+
for k, values := range m {
67+
for _, v := range values {
68+
r.Metadata = append(r.Metadata, &KeyValue{
69+
Key: k,
70+
Value: v,
71+
})
72+
}
73+
}
74+
}
75+
76+
func (m MD) fromRequest(r *Request) {
77+
for _, kv := range r.Metadata {
78+
m[kv.Key] = append(m[kv.Key], kv.Value)
79+
}
80+
}
81+
6182
type metadataKey struct{}
6283

6384
// GetMetadata retrieves metadata from context.Context (previously attached with WithMetadata)
64-
func GetMetadata(ctx context.Context) (Metadata, bool) {
65-
metadata, ok := ctx.Value(metadataKey{}).(Metadata)
85+
func GetMetadata(ctx context.Context) (MD, bool) {
86+
metadata, ok := ctx.Value(metadataKey{}).(MD)
6687
return metadata, ok
6788
}
6889

@@ -81,6 +102,6 @@ func GetMetadataValue(ctx context.Context, name string) (string, bool) {
81102
}
82103

83104
// WithMetadata attaches metadata map to a context.Context
84-
func WithMetadata(ctx context.Context, headers Metadata) context.Context {
85-
return context.WithValue(ctx, metadataKey{}, headers)
105+
func WithMetadata(ctx context.Context, md MD) context.Context {
106+
return context.WithValue(ctx, metadataKey{}, md)
86107
}

metadata_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import (
2121
"testing"
2222
)
2323

24-
func TestMetadata_Get(t *testing.T) {
25-
metadata := make(Metadata)
24+
func TestMetadataGet(t *testing.T) {
25+
metadata := make(MD)
2626
metadata.Set("foo", "1", "2")
2727

2828
if list, ok := metadata.Get("foo"); !ok {
@@ -36,17 +36,17 @@ func TestMetadata_Get(t *testing.T) {
3636
}
3737
}
3838

39-
func TestMetadata_GetInvalidKey(t *testing.T) {
40-
metadata := make(Metadata)
39+
func TestMetadataGetInvalidKey(t *testing.T) {
40+
metadata := make(MD)
4141
metadata.Set("foo", "1", "2")
4242

4343
if _, ok := metadata.Get("invalid"); ok {
4444
t.Error("found invalid key")
4545
}
4646
}
4747

48-
func TestMetadata_Unset(t *testing.T) {
49-
metadata := make(Metadata)
48+
func TestMetadataUnset(t *testing.T) {
49+
metadata := make(MD)
5050
metadata.Set("foo", "1", "2")
5151
metadata.Set("foo")
5252

@@ -55,8 +55,8 @@ func TestMetadata_Unset(t *testing.T) {
5555
}
5656
}
5757

58-
func TestMetadata_Replace(t *testing.T) {
59-
metadata := make(Metadata)
58+
func TestMetadataReplace(t *testing.T) {
59+
metadata := make(MD)
6060
metadata.Set("foo", "1", "2")
6161
metadata.Set("foo", "3", "4")
6262

@@ -71,8 +71,8 @@ func TestMetadata_Replace(t *testing.T) {
7171
}
7272
}
7373

74-
func TestMetadata_Append(t *testing.T) {
75-
metadata := make(Metadata)
74+
func TestMetadataAppend(t *testing.T) {
75+
metadata := make(MD)
7676
metadata.Set("foo", "1")
7777
metadata.Append("foo", "2")
7878
metadata.Append("bar", "3")
@@ -94,8 +94,8 @@ func TestMetadata_Append(t *testing.T) {
9494
}
9595
}
9696

97-
func TestMetadata_Context(t *testing.T) {
98-
metadata := make(Metadata)
97+
func TestMetadataContext(t *testing.T) {
98+
metadata := make(MD)
9999
metadata.Set("foo", "bar")
100100

101101
ctx := WithMetadata(context.Background(), metadata)

server.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,10 @@ func (c *serverConn) run(sctx context.Context) {
469469
var noopFunc = func() {}
470470

471471
func getRequestContext(ctx context.Context, req *Request) (retCtx context.Context, cancel func()) {
472-
if req.Metadata != nil {
473-
ctx = WithMetadata(ctx, req.Metadata)
472+
if len(req.Metadata) > 0 {
473+
md := MD{}
474+
md.fromRequest(req)
475+
ctx = WithMetadata(ctx, md)
474476
}
475477

476478
cancel = noopFunc

server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ func roundTrip(ctx context.Context, t *testing.T, client *testingClient, value s
546546
}
547547
)
548548

549-
ctx = WithMetadata(ctx, Metadata{"foo": makeStringList("bar")})
549+
ctx = WithMetadata(ctx, MD{"foo": []string{"bar"}})
550550

551551
resp, err := client.Test(ctx, tp)
552552
if err != nil {

types.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import (
2323
)
2424

2525
type Request struct {
26-
Service string `protobuf:"bytes,1,opt,name=service,proto3"`
27-
Method string `protobuf:"bytes,2,opt,name=method,proto3"`
28-
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"`
29-
TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,proto3"`
30-
Metadata Metadata `protobuf:"bytes,5,opt,name=metadata,proto3" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
26+
Service string `protobuf:"bytes,1,opt,name=service,proto3"`
27+
Method string `protobuf:"bytes,2,opt,name=method,proto3"`
28+
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"`
29+
TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,proto3"`
30+
Metadata []*KeyValue `protobuf:"bytes,5,rep,name=metadata,proto3"`
3131
}
3232

3333
func (r *Request) Reset() { *r = Request{} }
@@ -52,3 +52,12 @@ func (r *StringList) String() string { return fmt.Sprintf("%+#v", r) }
5252
func (r *StringList) ProtoMessage() {}
5353

5454
func makeStringList(item ...string) StringList { return StringList{List: item} }
55+
56+
type KeyValue struct {
57+
Key string `protobuf:"bytes,1,opt,name=key,proto3"`
58+
Value string `protobuf:"bytes,2,opt,name=value,proto3"`
59+
}
60+
61+
func (m *KeyValue) Reset() { *m = KeyValue{} }
62+
func (*KeyValue) ProtoMessage() {}
63+
func (m *KeyValue) String() string { return fmt.Sprintf("%+#v", m) }

0 commit comments

Comments
 (0)