From 484e2d96e586812e3cb446badd27b41d521e9b54 Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 16:06:27 -0700 Subject: [PATCH 1/6] change the metadata datastructure --- metadata/metadata.go | 12 +++++++----- test/end2end_test.go | 13 +++++++++---- transport/http2_client.go | 5 ++++- transport/http2_server.go | 9 +++++++-- transport/http_util.go | 6 +++--- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/metadata/metadata.go b/metadata/metadata.go index 8b4ed9e1..e910f9a8 100644 --- a/metadata/metadata.go +++ b/metadata/metadata.go @@ -64,7 +64,7 @@ func encodeKeyValue(k, v string) (string, string) { if isASCII(v) { return k, v } - key := k + binHdrSuffix + key := strings.ToLower(k + binHdrSuffix) val := base64.StdEncoding.EncodeToString([]byte(v)) return key, string(val) } @@ -85,14 +85,14 @@ func DecodeKeyValue(k, v string) (string, string, error) { // MD is a mapping from metadata keys to values. Users should use the following // two convenience functions New and Pairs to generate MD. -type MD map[string]string +type MD map[string][]string // New creates a MD from given key-value map. func New(m map[string]string) MD { md := MD{} for k, v := range m { key, val := encodeKeyValue(k, v) - md[key] = val + md[key] = append(md[key],val) } return md } @@ -111,7 +111,7 @@ func Pairs(kv ...string) MD { continue } key, val := encodeKeyValue(k, s) - md[key] = val + md[key] = append(md[key],val) } return md } @@ -125,7 +125,9 @@ func (md MD) Len() int { func (md MD) Copy() MD { out := MD{} for k, v := range md { - out[k] = v + for _, i := range v { + out[k] = append(out[k],i) + } } return out } diff --git a/test/end2end_test.go b/test/end2end_test.go index fb83b452..c23d8262 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -59,8 +59,8 @@ import ( var ( testMetadata = metadata.MD{ - "key1": "value1", - "key2": "value2", + "key1": []string{"value1"}, + "key2": []string{"value2"}, } testAppUA = "myApp1/1.0 myApp2/0.9" ) @@ -75,7 +75,12 @@ func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.E if _, ok := md["user-agent"]; !ok { return nil, grpc.Errorf(codes.DataLoss, "got extra metadata") } - grpc.SendHeader(ctx, metadata.Pairs("ua", md["user-agent"])) + // kv := []string{"ua"} + // for _, entry := range md["user-agent"]{ + // kv = append(kv,entry) + // } + // grpc.SendHeader(ctx, metadata.Pairs(kv)) + grpc.SendHeader(ctx, metadata.Pairs("ua", md["user-agent"][0])) } return new(testpb.Empty), nil } @@ -499,7 +504,7 @@ func testEmptyUnaryWithUserAgent(t *testing.T, e env) { if err != nil || !proto.Equal(&testpb.Empty{}, reply) { t.Fatalf("TestService/EmptyCall(_, _) = %v, %v, want %v, ", reply, err, &testpb.Empty{}) } - if v, ok := header["ua"]; !ok || v != testAppUA { + if v, ok := header["ua"]; !ok || v[0] != testAppUA { t.Fatalf("header[\"ua\"] = %q, %t, want %q, true", v, ok, testAppUA) } tearDown(s, cc) diff --git a/transport/http2_client.go b/transport/http2_client.go index 0986ef01..02147e97 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -294,9 +294,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea if md, ok := metadata.FromContext(ctx); ok { hasMD = true for k, v := range md { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) + for _, entry := range v { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } } + + } first := true // Sends the headers in a single batch even when they span multiple frames. for !endHeaders { diff --git a/transport/http2_server.go b/transport/http2_server.go index 2ec2bb13..a8e78cdb 100644 --- a/transport/http2_server.go +++ b/transport/http2_server.go @@ -440,8 +440,11 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) for k, v := range md { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) + for _, entry := range v{ + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } +} + if err := t.writeHeaders(s, t.hBuf, false); err != nil { return err } @@ -473,8 +476,10 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: statusDesc}) // Attach the trailer metadata. for k, v := range s.trailer { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) + for _, entry := range v { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } +} if err := t.writeHeaders(s, t.hBuf, true); err != nil { t.Close() return err diff --git a/transport/http_util.go b/transport/http_util.go index af84fbf6..6cc8d335 100644 --- a/transport/http_util.go +++ b/transport/http_util.go @@ -100,7 +100,7 @@ type decodeState struct { timeout time.Duration method string // key-value metadata map from the peer. - mdata map[string]string + mdata map[string][]string } // An hpackDecoder decodes HTTP2 headers which may span multiple frames. @@ -173,14 +173,14 @@ func newHPACKDecoder() *hpackDecoder { f.Value = f.Value[:i] } if d.state.mdata == nil { - d.state.mdata = make(map[string]string) + d.state.mdata = make(map[string][]string) } k, v, err := metadata.DecodeKeyValue(f.Name, f.Value) if err != nil { grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err) return } - d.state.mdata[k] = v + d.state.mdata[k]= append(d.state.mdata[k],v) } } }) From 54f53f005efaa9a65ff142025971f2e04d7204b6 Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 16:10:19 -0700 Subject: [PATCH 2/6] remove unused code --- interop/client/client.go | 10 ++++++++-- test/end2end_test.go | 7 +------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/interop/client/client.go b/interop/client/client.go index cc599cf4..4f952076 100644 --- a/interop/client/client.go +++ b/interop/client/client.go @@ -304,8 +304,8 @@ func doServiceAccountCreds(tc testpb.TestServiceClient) { var ( testMetadata = metadata.MD{ - "key1": "value1", - "key2": "value2", + "key1": []string{"value1"}, + "key2": []string{"value2"}, } ) @@ -381,6 +381,12 @@ func main() { grpclog.Fatalf("Failed to create JWT credentials: %v", err) } opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) + } else if *testCase == "jwt_token_creds" { + jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope) + if err != nil { + grpclog.Fatalf("Failed to create JWT credentials: %v", err) + } + opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) } } conn, err := grpc.Dial(serverAddr, opts...) diff --git a/test/end2end_test.go b/test/end2end_test.go index c23d8262..d436d03e 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -75,12 +75,7 @@ func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.E if _, ok := md["user-agent"]; !ok { return nil, grpc.Errorf(codes.DataLoss, "got extra metadata") } - // kv := []string{"ua"} - // for _, entry := range md["user-agent"]{ - // kv = append(kv,entry) - // } - // grpc.SendHeader(ctx, metadata.Pairs(kv)) - grpc.SendHeader(ctx, metadata.Pairs("ua", md["user-agent"][0])) + grpc.SendHeader(ctx, metadata.Pairs("ua", md["user-agent"][0])) } return new(testpb.Empty), nil } From bf963e1bb362a54d80702358bbf397cd2f75567b Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 16:59:16 -0700 Subject: [PATCH 3/6] change end2end test --- interop/client/client.go | 6 ------ test/end2end_test.go | 6 +++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/interop/client/client.go b/interop/client/client.go index 4f952076..4dd98123 100644 --- a/interop/client/client.go +++ b/interop/client/client.go @@ -381,12 +381,6 @@ func main() { grpclog.Fatalf("Failed to create JWT credentials: %v", err) } opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) - } else if *testCase == "jwt_token_creds" { - jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope) - if err != nil { - grpclog.Fatalf("Failed to create JWT credentials: %v", err) - } - opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) } } conn, err := grpc.Dial(serverAddr, opts...) diff --git a/test/end2end_test.go b/test/end2end_test.go index d436d03e..5696153c 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -75,7 +75,11 @@ func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.E if _, ok := md["user-agent"]; !ok { return nil, grpc.Errorf(codes.DataLoss, "got extra metadata") } - grpc.SendHeader(ctx, metadata.Pairs("ua", md["user-agent"][0])) + var str []string + for _,entry := range md["user-agent"]{ + str = append(str,"ua",entry) + } + grpc.SendHeader(ctx, metadata.Pairs(str...)) } return new(testpb.Empty), nil } From 1f14f6f0c5e03be39ea9c3f8b2627aec0791f963 Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 17:34:20 -0700 Subject: [PATCH 4/6] gofmt --- metadata/metadata.go | 6 +++--- test/end2end_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/metadata/metadata.go b/metadata/metadata.go index e910f9a8..adebc38f 100644 --- a/metadata/metadata.go +++ b/metadata/metadata.go @@ -92,7 +92,7 @@ func New(m map[string]string) MD { md := MD{} for k, v := range m { key, val := encodeKeyValue(k, v) - md[key] = append(md[key],val) + md[key] = append(md[key], val) } return md } @@ -111,7 +111,7 @@ func Pairs(kv ...string) MD { continue } key, val := encodeKeyValue(k, s) - md[key] = append(md[key],val) + md[key] = append(md[key], val) } return md } @@ -126,7 +126,7 @@ func (md MD) Copy() MD { out := MD{} for k, v := range md { for _, i := range v { - out[k] = append(out[k],i) + out[k] = append(out[k], i) } } return out diff --git a/test/end2end_test.go b/test/end2end_test.go index 5696153c..761f25a1 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -76,8 +76,8 @@ func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.E return nil, grpc.Errorf(codes.DataLoss, "got extra metadata") } var str []string - for _,entry := range md["user-agent"]{ - str = append(str,"ua",entry) + for _, entry := range md["user-agent"] { + str = append(str, "ua", entry) } grpc.SendHeader(ctx, metadata.Pairs(str...)) } From 4074c45c3f605943b4765caedf82235e041f9885 Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 17:40:00 -0700 Subject: [PATCH 5/6] gofmt --- transport/http2_client.go | 4 ++-- transport/http2_server.go | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/transport/http2_client.go b/transport/http2_client.go index 02147e97..eac2ce99 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -295,9 +295,9 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea hasMD = true for k, v := range md { for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + } } - } } first := true diff --git a/transport/http2_server.go b/transport/http2_server.go index a8e78cdb..006ddeae 100644 --- a/transport/http2_server.go +++ b/transport/http2_server.go @@ -440,10 +440,10 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) for k, v := range md { - for _, entry := range v{ - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + for _, entry := range v { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + } } -} if err := t.writeHeaders(s, t.hBuf, false); err != nil { return err @@ -477,9 +477,9 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s // Attach the trailer metadata. for k, v := range s.trailer { for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + } } -} if err := t.writeHeaders(s, t.hBuf, true); err != nil { t.Close() return err From 676c10ae4d4f9c91cd436295bee5b5577d5a2f7f Mon Sep 17 00:00:00 2001 From: yangzhouhan Date: Mon, 10 Aug 2015 17:42:54 -0700 Subject: [PATCH 6/6] gofmt --- transport/http2_client.go | 1 - transport/http2_server.go | 1 - transport/http_util.go | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/transport/http2_client.go b/transport/http2_client.go index eac2ce99..03480b7e 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -298,7 +298,6 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } } - } first := true // Sends the headers in a single batch even when they span multiple frames. diff --git a/transport/http2_server.go b/transport/http2_server.go index 006ddeae..79e2b200 100644 --- a/transport/http2_server.go +++ b/transport/http2_server.go @@ -444,7 +444,6 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } } - if err := t.writeHeaders(s, t.hBuf, false); err != nil { return err } diff --git a/transport/http_util.go b/transport/http_util.go index 6cc8d335..ef07924c 100644 --- a/transport/http_util.go +++ b/transport/http_util.go @@ -180,7 +180,7 @@ func newHPACKDecoder() *hpackDecoder { grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err) return } - d.state.mdata[k]= append(d.state.mdata[k],v) + d.state.mdata[k] = append(d.state.mdata[k], v) } } })