Skip to content

Commit d43d31e

Browse files
Merge 4f808fe into e9870cb
2 parents e9870cb + 4f808fe commit d43d31e

File tree

10 files changed

+212
-54
lines changed

10 files changed

+212
-54
lines changed

metadata/metadata.go

+27-7
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,61 @@ import (
99
// Metadata is our way of representing request headers internally.
1010
// They're used at the RPC level and translate back and forth
1111
// from Transport headers.
12-
type Metadata map[string]string
12+
type Metadata map[string][]string
1313

1414
// New creates an MD from a given key-values map.
15-
func New(mds ...map[string]string) Metadata {
15+
func New(mds ...map[string][]string) Metadata {
1616
md := Metadata{}
1717
for _, m := range mds {
18-
for k, v := range m {
19-
md.Set(k, v)
18+
for k, vList := range m {
19+
for _, v := range vList {
20+
md.Add(k, v)
21+
}
2022
}
2123
}
2224
return md
2325
}
2426

27+
// Add adds the key, value pair to the header.
28+
func (m Metadata) Add(key, value string) {
29+
if len(key) == 0 {
30+
return
31+
}
32+
33+
m[strings.ToLower(key)] = append(m[strings.ToLower(key)], value)
34+
}
35+
2536
// Get returns the value associated with the passed key.
2637
func (m Metadata) Get(key string) string {
27-
return m[strings.ToLower(key)]
38+
v := m[strings.ToLower(key)]
39+
if len(v) == 0 {
40+
return ""
41+
}
42+
return v[0]
2843
}
2944

3045
// Set stores the key-value pair.
3146
func (m Metadata) Set(key string, value string) {
3247
if key == "" || value == "" {
3348
return
3449
}
35-
m[strings.ToLower(key)] = value
50+
m[strings.ToLower(key)] = []string{value}
3651
}
3752

3853
// Range iterate over element in metadata.
39-
func (m Metadata) Range(f func(k, v string) bool) {
54+
func (m Metadata) Range(f func(k string, v []string) bool) {
4055
for k, v := range m {
4156
if !f(k, v) {
4257
break
4358
}
4459
}
4560
}
4661

62+
// Values returns a slice of values associated with the passed key.
63+
func (m Metadata) Values(key string) []string {
64+
return m[strings.ToLower(key)]
65+
}
66+
4767
// Clone returns a deep copy of Metadata
4868
func (m Metadata) Clone() Metadata {
4969
md := make(Metadata, len(m))

metadata/metadata_test.go

+103-31
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
func TestNew(t *testing.T) {
1010
type args struct {
11-
mds []map[string]string
11+
mds []map[string][]string
1212
}
1313
tests := []struct {
1414
name string
@@ -17,13 +17,13 @@ func TestNew(t *testing.T) {
1717
}{
1818
{
1919
name: "hello",
20-
args: args{[]map[string]string{{"hello": "kratos"}, {"hello2": "go-kratos"}}},
21-
want: Metadata{"hello": "kratos", "hello2": "go-kratos"},
20+
args: args{[]map[string][]string{{"hello": {"kratos"}}, {"hello2": {"go-kratos"}}}},
21+
want: Metadata{"hello": {"kratos"}, "hello2": {"go-kratos"}},
2222
},
2323
{
2424
name: "hi",
25-
args: args{[]map[string]string{{"hi": "kratos"}, {"hi2": "go-kratos"}}},
26-
want: Metadata{"hi": "kratos", "hi2": "go-kratos"},
25+
args: args{[]map[string][]string{{"hi": {"kratos"}}, {"hi2": {"go-kratos"}}}},
26+
want: Metadata{"hi": {"kratos"}, "hi2": {"go-kratos"}},
2727
},
2828
}
2929
for _, tt := range tests {
@@ -47,13 +47,13 @@ func TestMetadata_Get(t *testing.T) {
4747
}{
4848
{
4949
name: "kratos",
50-
m: Metadata{"kratos": "value", "env": "dev"},
50+
m: Metadata{"kratos": {"value"}, "env": {"dev"}},
5151
args: args{key: "kratos"},
5252
want: "value",
5353
},
5454
{
5555
name: "env",
56-
m: Metadata{"kratos": "value", "env": "dev"},
56+
m: Metadata{"kratos": {"value"}, "env": {"dev"}},
5757
args: args{key: "env"},
5858
want: "dev",
5959
},
@@ -67,6 +67,38 @@ func TestMetadata_Get(t *testing.T) {
6767
}
6868
}
6969

70+
func TestMetadata_Values(t *testing.T) {
71+
type args struct {
72+
key string
73+
}
74+
tests := []struct {
75+
name string
76+
m Metadata
77+
args args
78+
want []string
79+
}{
80+
{
81+
name: "kratos",
82+
m: Metadata{"kratos": {"value", "value2"}, "env": {"dev"}},
83+
args: args{key: "kratos"},
84+
want: []string{"value", "value2"},
85+
},
86+
{
87+
name: "env",
88+
m: Metadata{"kratos": {"value", "value2"}, "env": {"dev"}},
89+
args: args{key: "env"},
90+
want: []string{"dev"},
91+
},
92+
}
93+
for _, tt := range tests {
94+
t.Run(tt.name, func(t *testing.T) {
95+
if got := tt.m.Values(tt.args.key); !reflect.DeepEqual(got, tt.want) {
96+
t.Errorf("Get() = %v, want %v", got, tt.want)
97+
}
98+
})
99+
}
100+
}
101+
70102
func TestMetadata_Set(t *testing.T) {
71103
type args struct {
72104
key string
@@ -82,13 +114,13 @@ func TestMetadata_Set(t *testing.T) {
82114
name: "kratos",
83115
m: Metadata{},
84116
args: args{key: "hello", value: "kratos"},
85-
want: Metadata{"hello": "kratos"},
117+
want: Metadata{"hello": {"kratos"}},
86118
},
87119
{
88120
name: "env",
89-
m: Metadata{"hello": "kratos"},
121+
m: Metadata{"hello": {"kratos"}},
90122
args: args{key: "env", value: "pro"},
91-
want: Metadata{"hello": "kratos", "env": "pro"},
123+
want: Metadata{"hello": {"kratos"}, "env": {"pro"}},
92124
},
93125
{
94126
name: "empty",
@@ -107,6 +139,46 @@ func TestMetadata_Set(t *testing.T) {
107139
}
108140
}
109141

142+
func TestMetadata_Add(t *testing.T) {
143+
type args struct {
144+
key string
145+
value string
146+
}
147+
tests := []struct {
148+
name string
149+
m Metadata
150+
args args
151+
want Metadata
152+
}{
153+
{
154+
name: "kratos",
155+
m: Metadata{},
156+
args: args{key: "hello", value: "kratos"},
157+
want: Metadata{"hello": {"kratos"}},
158+
},
159+
{
160+
name: "env",
161+
m: Metadata{"hello": {"kratos"}},
162+
args: args{key: "hello", value: "again"},
163+
want: Metadata{"hello": {"kratos", "again"}},
164+
},
165+
{
166+
name: "empty",
167+
m: Metadata{},
168+
args: args{key: "", value: ""},
169+
want: Metadata{},
170+
},
171+
}
172+
for _, tt := range tests {
173+
t.Run(tt.name, func(t *testing.T) {
174+
tt.m.Add(tt.args.key, tt.args.value)
175+
if !reflect.DeepEqual(tt.m, tt.want) {
176+
t.Errorf("Set() = %v, want %v", tt.m, tt.want)
177+
}
178+
})
179+
}
180+
}
181+
110182
func TestClientContext(t *testing.T) {
111183
type args struct {
112184
ctx context.Context
@@ -118,11 +190,11 @@ func TestClientContext(t *testing.T) {
118190
}{
119191
{
120192
name: "kratos",
121-
args: args{context.Background(), Metadata{"hello": "kratos", "kratos": "https://go-kratos.dev"}},
193+
args: args{context.Background(), Metadata{"hello": {"kratos"}, "kratos": {"https://go-kratos.dev"}}},
122194
},
123195
{
124196
name: "hello",
125-
args: args{context.Background(), Metadata{"hello": "kratos", "hello2": "https://go-kratos.dev"}},
197+
args: args{context.Background(), Metadata{"hello": {"kratos"}, "hello2": {"https://go-kratos.dev"}}},
126198
},
127199
}
128200
for _, tt := range tests {
@@ -151,11 +223,11 @@ func TestServerContext(t *testing.T) {
151223
}{
152224
{
153225
name: "kratos",
154-
args: args{context.Background(), Metadata{"hello": "kratos", "kratos": "https://go-kratos.dev"}},
226+
args: args{context.Background(), Metadata{"hello": {"kratos"}, "kratos": {"https://go-kratos.dev"}}},
155227
},
156228
{
157229
name: "hello",
158-
args: args{context.Background(), Metadata{"hello": "kratos", "hello2": "https://go-kratos.dev"}},
230+
args: args{context.Background(), Metadata{"hello": {"kratos"}, "hello2": {"https://go-kratos.dev"}}},
159231
},
160232
}
161233
for _, tt := range tests {
@@ -186,12 +258,12 @@ func TestAppendToClientContext(t *testing.T) {
186258
{
187259
name: "kratos",
188260
args: args{Metadata{}, []string{"hello", "kratos", "env", "dev"}},
189-
want: Metadata{"hello": "kratos", "env": "dev"},
261+
want: Metadata{"hello": {"kratos"}, "env": {"dev"}},
190262
},
191263
{
192264
name: "hello",
193-
args: args{Metadata{"hi": "https://go-kratos.dev/"}, []string{"hello", "kratos", "env", "dev"}},
194-
want: Metadata{"hello": "kratos", "env": "dev", "hi": "https://go-kratos.dev/"},
265+
args: args{Metadata{"hi": {"https://go-kratos.dev/"}}, []string{"hello", "kratos", "env", "dev"}},
266+
want: Metadata{"hello": {"kratos"}, "env": {"dev"}, "hi": {"https://go-kratos.dev/"}},
195267
},
196268
}
197269
for _, tt := range tests {
@@ -240,13 +312,13 @@ func TestMergeToClientContext(t *testing.T) {
240312
}{
241313
{
242314
name: "kratos",
243-
args: args{Metadata{}, Metadata{"hello": "kratos", "env": "dev"}},
244-
want: Metadata{"hello": "kratos", "env": "dev"},
315+
args: args{Metadata{}, Metadata{"hello": {"kratos"}, "env": {"dev"}}},
316+
want: Metadata{"hello": {"kratos"}, "env": {"dev"}},
245317
},
246318
{
247319
name: "hello",
248-
args: args{Metadata{"hi": "https://go-kratos.dev/"}, Metadata{"hello": "kratos", "env": "dev"}},
249-
want: Metadata{"hello": "kratos", "env": "dev", "hi": "https://go-kratos.dev/"},
320+
args: args{Metadata{"hi": {"https://go-kratos.dev/"}}, Metadata{"hello": {"kratos"}, "env": {"dev"}}},
321+
want: Metadata{"hello": {"kratos"}, "env": {"dev"}, "hi": {"https://go-kratos.dev/"}},
250322
},
251323
}
252324
for _, tt := range tests {
@@ -265,19 +337,19 @@ func TestMergeToClientContext(t *testing.T) {
265337
}
266338

267339
func TestMetadata_Range(t *testing.T) {
268-
md := Metadata{"kratos": "kratos", "https://go-kratos.dev/": "https://go-kratos.dev/", "go-kratos": "go-kratos"}
340+
md := Metadata{"kratos": {"kratos"}, "https://go-kratos.dev/": {"https://go-kratos.dev/"}, "go-kratos": {"go-kratos"}}
269341
tmp := Metadata{}
270-
md.Range(func(k, v string) bool {
342+
md.Range(func(k string, v []string) bool {
271343
if k == "https://go-kratos.dev/" || k == "kratos" {
272344
tmp[k] = v
273345
}
274346
return true
275347
})
276-
if !reflect.DeepEqual(tmp, Metadata{"https://go-kratos.dev/": "https://go-kratos.dev/", "kratos": "kratos"}) {
277-
t.Errorf("metadata = %v, want %v", tmp, Metadata{"https://go-kratos.dev/": "https://go-kratos.dev/", "kratos": "kratos"})
348+
if !reflect.DeepEqual(tmp, Metadata{"https://go-kratos.dev/": {"https://go-kratos.dev/"}, "kratos": {"kratos"}}) {
349+
t.Errorf("metadata = %v, want %v", tmp, Metadata{"https://go-kratos.dev/": {"https://go-kratos.dev/"}, "kratos": {"kratos"}})
278350
}
279351
tmp = Metadata{}
280-
md.Range(func(k, v string) bool {
352+
md.Range(func(k string, v []string) bool {
281353
return false
282354
})
283355
if !reflect.DeepEqual(tmp, Metadata{}) {
@@ -293,13 +365,13 @@ func TestMetadata_Clone(t *testing.T) {
293365
}{
294366
{
295367
name: "kratos",
296-
m: Metadata{"kratos": "kratos", "https://go-kratos.dev/": "https://go-kratos.dev/", "go-kratos": "go-kratos"},
297-
want: Metadata{"kratos": "kratos", "https://go-kratos.dev/": "https://go-kratos.dev/", "go-kratos": "go-kratos"},
368+
m: Metadata{"kratos": {"kratos"}, "https://go-kratos.dev/": {"https://go-kratos.dev/"}, "go-kratos": {"go-kratos"}},
369+
want: Metadata{"kratos": {"kratos"}, "https://go-kratos.dev/": {"https://go-kratos.dev/"}, "go-kratos": {"go-kratos"}},
298370
},
299371
{
300372
name: "go",
301-
m: Metadata{"language": "golang"},
302-
want: Metadata{"language": "golang"},
373+
m: Metadata{"language": {"golang"}},
374+
want: Metadata{"language": {"golang"}},
303375
},
304376
}
305377
for _, tt := range tests {
@@ -308,7 +380,7 @@ func TestMetadata_Clone(t *testing.T) {
308380
if !reflect.DeepEqual(got, tt.want) {
309381
t.Errorf("Clone() = %v, want %v", got, tt.want)
310382
}
311-
got["kratos"] = "go"
383+
got["kratos"] = []string{"go"}
312384
if reflect.DeepEqual(got, tt.want) {
313385
t.Errorf("want got != want got %v want %v", got, tt.want)
314386
}

middleware/auth/jwt/jwt_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ func (hc headerCarrier) Get(key string) string { return http.Header(hc).Get(key)
2424

2525
func (hc headerCarrier) Set(key string, value string) { http.Header(hc).Set(key, value) }
2626

27+
func (hc headerCarrier) Add(key string, value string) { http.Header(hc).Add(key, value) }
28+
2729
// Keys lists the keys stored in this carrier.
2830
func (hc headerCarrier) Keys() []string {
2931
keys := make([]string, 0, len(hc))
@@ -33,6 +35,11 @@ func (hc headerCarrier) Keys() []string {
3335
return keys
3436
}
3537

38+
// Values returns a slice value associated with the passed key.
39+
func (hc headerCarrier) Values(key string) []string {
40+
return http.Header(hc).Values(key)
41+
}
42+
3643
func newTokenHeader(headerKey string, token string) *headerCarrier {
3744
header := &headerCarrier{}
3845
header.Set(headerKey, token)

middleware/metadata/metadata.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ func Server(opts ...Option) middleware.Middleware {
6060
header := tr.RequestHeader()
6161
for _, k := range header.Keys() {
6262
if options.hasPrefix(k) {
63-
md.Set(k, header.Get(k))
63+
for _, v := range header.Values(k) {
64+
md.Add(k, v)
65+
}
6466
}
6567
}
6668
ctx = metadata.NewServerContext(ctx, md)
@@ -86,19 +88,25 @@ func Client(opts ...Option) middleware.Middleware {
8688

8789
header := tr.RequestHeader()
8890
// x-md-local-
89-
for k, v := range options.md {
90-
header.Set(k, v)
91+
for k, vList := range options.md {
92+
for _, v := range vList {
93+
header.Add(k, v)
94+
}
9195
}
9296
if md, ok := metadata.FromClientContext(ctx); ok {
93-
for k, v := range md {
94-
header.Set(k, v)
97+
for k, vList := range md {
98+
for _, v := range vList {
99+
header.Add(k, v)
100+
}
95101
}
96102
}
97103
// x-md-global-
98104
if md, ok := metadata.FromServerContext(ctx); ok {
99-
for k, v := range md {
105+
for k, vList := range md {
100106
if options.hasPrefix(k) {
101-
header.Set(k, v)
107+
for _, v := range vList {
108+
header.Add(k, v)
109+
}
102110
}
103111
}
104112
}

0 commit comments

Comments
 (0)