metadata: write original md before appended md ()

This commit is contained in:
Yongzheng Lai
2019-06-26 01:34:12 +08:00
committed by Menghan Li
parent 70e8b38052
commit 7472edcc1e
2 changed files with 46 additions and 9 deletions
internal/transport
test

@ -441,6 +441,15 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr)
if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok { if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
var k string var k string
for k, vv := range md {
// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
if isReservedHeader(k) {
continue
}
for _, v := range vv {
headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
}
}
for _, vv := range added { for _, vv := range added {
for i, v := range vv { for i, v := range vv {
if i%2 == 0 { if i%2 == 0 {
@ -454,15 +463,6 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr)
headerFields = append(headerFields, hpack.HeaderField{Name: strings.ToLower(k), Value: encodeMetadataHeader(k, v)}) headerFields = append(headerFields, hpack.HeaderField{Name: strings.ToLower(k), Value: encodeMetadataHeader(k, v)})
} }
} }
for k, vv := range md {
// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
if isReservedHeader(k) {
continue
}
for _, v := range vv {
headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
}
}
} }
if md, ok := t.md.(*metadata.MD); ok { if md, ok := t.md.(*metadata.MD); ok {
for k, vv := range *md { for k, vv := range *md {

@ -3146,6 +3146,43 @@ func testMetadataUnaryRPC(t *testing.T, e env) {
} }
} }
func (s) TestMetadataOrderUnaryRPC(t *testing.T) {
for _, e := range listTestEnv() {
testMetadataOrderUnaryRPC(t, e)
}
}
func testMetadataOrderUnaryRPC(t *testing.T, e env) {
te := newTest(t, e)
te.startServer(&testServer{security: e.security})
defer te.tearDown()
tc := testpb.NewTestServiceClient(te.clientConn())
ctx := metadata.NewOutgoingContext(context.Background(), testMetadata)
ctx = metadata.AppendToOutgoingContext(ctx, "key1", "value2")
ctx = metadata.AppendToOutgoingContext(ctx, "key1", "value3")
// using Join to built expected metadata instead of FromOutgoingContext
newMetadata := metadata.Join(testMetadata, metadata.Pairs("key1", "value2", "key1", "value3"))
var header metadata.MD
if _, err := tc.UnaryCall(ctx, &testpb.SimpleRequest{}, grpc.Header(&header)); err != nil {
t.Fatal(err)
}
// Ignore optional response headers that Servers may set:
if header != nil {
delete(header, "trailer") // RFC 2616 says server SHOULD (but optional) declare trailers
delete(header, "date") // the Date header is also optional
delete(header, "user-agent")
delete(header, "content-type")
}
if !reflect.DeepEqual(header, newMetadata) {
t.Fatalf("Received header metadata %v, want %v", header, newMetadata)
}
}
func (s) TestMultipleSetTrailerUnaryRPC(t *testing.T) { func (s) TestMultipleSetTrailerUnaryRPC(t *testing.T) {
for _, e := range listTestEnv() { for _, e := range listTestEnv() {
testMultipleSetTrailerUnaryRPC(t, e) testMultipleSetTrailerUnaryRPC(t, e)