From 2769cae6bde4c6d4e178d0273a615fe52c1864ba Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 7 Apr 2017 16:36:14 -0700 Subject: [PATCH] vendor: upgrade grpc-gateway to v1.2.0 --- .../grpc-gateway/runtime/context.go | 50 ++++++++- .../grpc-gateway/runtime/errors.go | 4 +- .../runtime/internal/stream_chunk.pb.go | 30 ++++- .../grpc-gateway/runtime/pattern.go | 2 +- .../grpc-gateway/runtime/query.go | 106 ++++++++++++++++-- glide.lock | 6 +- glide.yaml | 2 +- 7 files changed, 177 insertions(+), 23 deletions(-) diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go index f248c738b..98eeb44c9 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go @@ -15,12 +15,17 @@ import ( "google.golang.org/grpc/metadata" ) -// MetadataHeaderPrefix is prepended to HTTP headers in order to convert them to -// gRPC metadata for incoming requests processed by grpc-gateway +// MetadataHeaderPrefix is the http prefix that represents custom metadata +// parameters to or from a gRPC call. const MetadataHeaderPrefix = "Grpc-Metadata-" + +// MetadataPrefix is the prefix for grpc-gateway supplied custom metadata fields. +const MetadataPrefix = "grpcgateway-" + // MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to // HTTP headers in a response handled by grpc-gateway const MetadataTrailerPrefix = "Grpc-Trailer-" + const metadataGrpcTimeout = "Grpc-Timeout" const xForwardedFor = "X-Forwarded-For" @@ -52,8 +57,12 @@ func AnnotateContext(ctx context.Context, req *http.Request) (context.Context, e for key, vals := range req.Header { for _, val := range vals { - if key == "Authorization" { + // For backwards-compatibility, pass through 'authorization' header with no prefix. + if strings.ToLower(key) == "authorization" { pairs = append(pairs, "authorization", val) + } + if isPermanentHTTPHeader(key) { + pairs = append(pairs, strings.ToLower(fmt.Sprintf("%s%s", MetadataPrefix, key)), val) continue } if strings.HasPrefix(key, MetadataHeaderPrefix) { @@ -141,3 +150,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/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go index 0d3cb3bf3..5a51d02c0 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go @@ -64,7 +64,7 @@ var ( type errorBody struct { Error string `protobuf:"bytes,1,name=error" json:"error"` - Code int `protobuf:"bytes,2,name=code" json:"code"` + Code int32 `protobuf:"varint,2,name=code" json:"code"` } //Make this also conform to proto.Message for builtin JSONPb Marshaler @@ -85,7 +85,7 @@ func DefaultHTTPError(ctx context.Context, marshaler Marshaler, w http.ResponseW w.Header().Set("Content-Type", marshaler.ContentType()) body := &errorBody{ Error: grpc.ErrorDesc(err), - Code: int(grpc.Code(err)), + Code: int32(grpc.Code(err)), } buf, merr := marshaler.Marshal(body) diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go index 6f837cfd5..9a1405564 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go @@ -42,6 +42,34 @@ func (m *StreamError) String() string { return proto.CompactTextStrin func (*StreamError) ProtoMessage() {} func (*StreamError) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (m *StreamError) GetGrpcCode() int32 { + if m != nil { + return m.GrpcCode + } + return 0 +} + +func (m *StreamError) GetHttpCode() int32 { + if m != nil { + return m.HttpCode + } + return 0 +} + +func (m *StreamError) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *StreamError) GetHttpStatus() string { + if m != nil { + return m.HttpStatus + } + return "" +} + func init() { proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError") } @@ -50,7 +78,7 @@ func init() { proto.RegisterFile("runtime/internal/stream_chunk.proto", fileDesc var fileDescriptor0 = []byte{ // 181 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x34, 0x8e, 0xbf, 0xee, 0x82, 0x30, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x8e, 0xbf, 0xee, 0x82, 0x30, 0x14, 0x85, 0xd3, 0xdf, 0x1f, 0x85, 0xcb, 0x46, 0x1c, 0x9a, 0x38, 0x48, 0x74, 0x61, 0x82, 0xc1, 0x37, 0xd0, 0xf8, 0x02, 0xb0, 0xb9, 0x90, 0x0a, 0x37, 0x40, 0x94, 0x96, 0xdc, 0x5e, 0x62, 0x5c, 0x7d, 0x72, 0xd3, 0x22, 0xe3, 0xf9, 0xbe, 0x73, 0x92, 0x03, 0x07, 0x9a, 0x34, 0xf7, 0x03, 0xe6, diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go index 3947dbea0..8a9ec2cda 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go @@ -21,7 +21,7 @@ type op struct { operand int } -// Pattern is a template pattern of http request paths defined in third_party/googleapis/google/api/http.proto. +// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto. type Pattern struct { // ops is a list of operations ops []op diff --git a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go index 56a919a52..69f0ba1d6 100644 --- a/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go +++ b/cmd/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go @@ -4,7 +4,9 @@ import ( "fmt" "net/url" "reflect" + "strconv" "strings" + "time" "github.com/golang/protobuf/proto" "github.com/grpc-ecosystem/grpc-gateway/utilities" @@ -38,13 +40,15 @@ func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values [] if m.Kind() != reflect.Ptr { return fmt.Errorf("unexpected type %T: %v", msg, msg) } + var props *proto.Properties m = m.Elem() for i, fieldName := range fieldPath { isLast := i == len(fieldPath)-1 if !isLast && m.Kind() != reflect.Struct { return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, ".")) } - f := fieldByProtoName(m, fieldName) + var f reflect.Value + f, props = fieldByProtoName(m, fieldName) if !f.IsValid() { grpclog.Printf("field not found in %T: %s", msg, strings.Join(fieldPath, ".")) return nil @@ -52,17 +56,20 @@ func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values [] switch f.Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: + if !isLast { + return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) + } m = f case reflect.Slice: // TODO(yugui) Support []byte if !isLast { return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, ".")) } - return populateRepeatedField(f, values) + return populateRepeatedField(f, values, props) case reflect.Ptr: if f.IsNil() { m = reflect.New(f.Type().Elem()) - f.Set(m) + f.Set(m.Convert(f.Type())) } m = f.Elem() continue @@ -80,39 +87,73 @@ func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values [] default: grpclog.Printf("too many field values: %s", strings.Join(fieldPath, ".")) } - return populateField(m, values[0]) + return populateField(m, values[0], props) } // fieldByProtoName looks up a field whose corresponding protobuf field name is "name". // "m" must be a struct value. It returns zero reflect.Value if no such field found. -func fieldByProtoName(m reflect.Value, name string) reflect.Value { +func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties) { props := proto.GetProperties(m.Type()) for _, p := range props.Prop { if p.OrigName == name { - return m.FieldByName(p.Name) + return m.FieldByName(p.Name), p } } - return reflect.Value{} + return reflect.Value{}, nil } -func populateRepeatedField(f reflect.Value, values []string) error { +func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error { elemType := f.Type().Elem() + + // is the destination field a slice of an enumeration type? + if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { + return populateFieldEnumRepeated(f, values, enumValMap) + } + conv, ok := convFromType[elemType.Kind()] if !ok { return fmt.Errorf("unsupported field type %s", elemType) } - f.Set(reflect.MakeSlice(f.Type(), len(values), len(values))) + f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) for i, v := range values { result := conv.Call([]reflect.Value{reflect.ValueOf(v)}) if err := result[1].Interface(); err != nil { return err.(error) } - f.Index(i).Set(result[0]) + f.Index(i).Set(result[0].Convert(f.Index(i).Type())) } return nil } -func populateField(f reflect.Value, value string) error { +func populateField(f reflect.Value, value string, props *proto.Properties) error { + // Handle well known type + type wkt interface { + XXX_WellKnownType() string + } + if wkt, ok := f.Addr().Interface().(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "Timestamp": + if value == "null" { + f.Field(0).SetInt(0) + f.Field(1).SetInt(0) + return nil + } + + t, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + f.Field(0).SetInt(int64(t.Unix())) + f.Field(1).SetInt(int64(t.Nanosecond())) + return nil + } + } + + // is the destination field an enumeration type? + if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { + return populateFieldEnum(f, value, enumValMap) + } + conv, ok := convFromType[f.Kind()] if !ok { return fmt.Errorf("unsupported field type %T", f) @@ -121,7 +162,48 @@ func populateField(f reflect.Value, value string) error { if err := result[1].Interface(); err != nil { return err.(error) } - f.Set(result[0]) + f.Set(result[0].Convert(f.Type())) + return nil +} + +func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) { + // see if it's an enumeration string + if enumVal, ok := enumValMap[value]; ok { + return reflect.ValueOf(enumVal).Convert(t), nil + } + + // check for an integer that matches an enumeration value + eVal, err := strconv.Atoi(value) + if err != nil { + return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) + } + for _, v := range enumValMap { + if v == int32(eVal) { + return reflect.ValueOf(eVal).Convert(t), nil + } + } + return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) +} + +func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error { + cval, err := convertEnum(value, f.Type(), enumValMap) + if err != nil { + return err + } + f.Set(cval) + return nil +} + +func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error { + elemType := f.Type().Elem() + f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) + for i, v := range values { + result, err := convertEnum(v, elemType, enumValMap) + if err != nil { + return err + } + f.Index(i).Set(result) + } return nil } diff --git a/glide.lock b/glide.lock index d1b3eafb0..526baf929 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: d546c79ab7f1bcc7b048995624e4353713fe1b5fad5d69a50202e309fe9dd2fc -updated: 2017-04-07T14:31:10.872688463-07:00 +hash: 96143db7f79ff5fad84bd66a435153981b793dc8df5e3ef7e55cd096959b6c73 +updated: 2017-04-07T16:28:46.088989482-07:00 imports: - name: github.com/beorn7/perks version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 @@ -54,7 +54,7 @@ imports: - name: github.com/grpc-ecosystem/go-grpc-prometheus version: 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 - name: github.com/grpc-ecosystem/grpc-gateway - version: 84398b94e188ee336f307779b57b3aa91af7063c + version: 18d159699f2e83fc5bb9ef2f79465ca3f3122676 subpackages: - runtime - runtime/internal diff --git a/glide.yaml b/glide.yaml index 24a99eeed..49d688931 100644 --- a/glide.yaml +++ b/glide.yaml @@ -40,7 +40,7 @@ import: - package: github.com/google/btree version: 925471ac9e2131377a91e1595defec898166fe49 - package: github.com/grpc-ecosystem/grpc-gateway - version: 84398b94e188ee336f307779b57b3aa91af7063c + version: v1.2.0 subpackages: - runtime - runtime/internal