diff --git a/runtime/context.go b/runtime/context.go index ad42535662a..73a9da2fe24 100644 --- a/runtime/context.go +++ b/runtime/context.go @@ -15,7 +15,7 @@ import ( "google.golang.org/grpc/metadata" ) -const metadataHeaderPrefix = "Grpc-Metadata-" +const metadataHeaderPrefix = "GrpcGateway-" const metadataTrailerPrefix = "Grpc-Trailer-" const metadataGrpcTimeout = "Grpc-Timeout" @@ -48,8 +48,8 @@ func AnnotateContext(ctx context.Context, req *http.Request) (context.Context, e for key, vals := range req.Header { for _, val := range vals { - if key == "Authorization" { - pairs = append(pairs, "authorization", val) + if isPermanentHTTPHeader(key) { + pairs = append(pairs, strings.ToLower(fmt.Sprintf("%s%s", metadataHeaderPrefix, key)), val) continue } if strings.HasPrefix(key, metadataHeaderPrefix) { @@ -137,3 +137,38 @@ func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { } return } + +// isPermanentHTTPHeader checks whether hdr belongs to the list of +// permenant request headers maintained by IANA. +// http://www.iana.org/assignments/message-headers/message-headers.xml +func isPermanentHTTPHeader(hdr string) bool { + switch hdr { + case + "Accept", + "Accept-Charset", + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Cache-Control", + "Content-Type", + "Cookie", + "Date", + "Expect", + "From", + "Host", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Schedule-Tag-Match", + "If-Unmodified-Since", + "Max-Forwards", + "Origin", + "Pragma", + "Referer", + "User-Agent", + "Via", + "Warning": + return true + } + return false +} diff --git a/runtime/context_test.go b/runtime/context_test.go index abc1873fad9..ce40944d8b0 100644 --- a/runtime/context_test.go +++ b/runtime/context_test.go @@ -1,6 +1,7 @@ package runtime_test import ( + "fmt" "net/http" "reflect" "testing" @@ -41,9 +42,9 @@ func TestAnnotateContext_ForwardsGrpcMetadata(t *testing.T) { t.Fatalf("http.NewRequest(%q, %q, nil) failed with %v; want success", "GET", "http://www.example.com", err) } request.Header.Add("Some-Irrelevant-Header", "some value") - request.Header.Add("Grpc-Metadata-FooBar", "Value1") - request.Header.Add("Grpc-Metadata-Foo-BAZ", "Value2") - request.Header.Add("Grpc-Metadata-foo-bAz", "Value3") + request.Header.Add("GrpcGateway-FooBar", "Value1") + request.Header.Add("GrpcGateway-Foo-BAZ", "Value2") + request.Header.Add("GrpcGateway-foo-bAz", "Value3") request.Header.Add("Authorization", "Token 1234567890") annotated, err := runtime.AnnotateContext(ctx, request) if err != nil { @@ -52,16 +53,16 @@ func TestAnnotateContext_ForwardsGrpcMetadata(t *testing.T) { } md, ok := metadata.FromContext(annotated) if got, want := len(md), emptyForwardMetaCount+3; !ok || got != want { - t.Errorf("Expected %d metadata items in context; got %d", got, want) + t.Errorf("Expected %d metadata items in context; got %d. md = %+v", got, want, md) } if got, want := md["foobar"], []string{"Value1"}; !reflect.DeepEqual(got, want) { - t.Errorf(`md["foobar"] = %q; want %q`, got, want) + t.Errorf(`md["GrpcGateway-foobar"] = %q; want %q`, got, want) } if got, want := md["foo-baz"], []string{"Value2", "Value3"}; !reflect.DeepEqual(got, want) { - t.Errorf(`md["foo-baz"] = %q want %q`, got, want) + t.Errorf(`md["GrpcGateway-foo-baz"] = %q want %q`, got, want) } if got, want := md["authorization"], []string{"Token 1234567890"}; !reflect.DeepEqual(got, want) { - t.Errorf(`md["authorization"] = %q want %q`, got, want) + t.Errorf(`md["GrpcGateway-authorization"] = %q want %q`, got, want) } }