Browse Source

Merge pull request #7695 from heyitsanthony/upgrade-grpc-gateway

vendor: upgrade grpc-gateway to v1.2.0
Anthony Romano 8 years ago
parent
commit
55e2355326

+ 47 - 3
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
+}

+ 2 - 2
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)

+ 29 - 1
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,

+ 1 - 1
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

+ 94 - 12
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
 }
 

+ 3 - 3
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

+ 1 - 1
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