mirror of https://github.com/grpc/grpc-go.git
metadata: write original md before appended md (#2879)
This commit is contained in:
parent
70e8b38052
commit
7472edcc1e
|
@ -441,6 +441,15 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr)
|
|||
|
||||
if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
|
||||
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 i, v := range vv {
|
||||
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)})
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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) {
|
||||
for _, e := range listTestEnv() {
|
||||
testMultipleSetTrailerUnaryRPC(t, e)
|
||||
|
|
Loading…
Reference in New Issue