add path for rpc stub (#947)

* add path for rpc stub

* fix http body and response_body

Co-authored-by: chenzhihui <zhihui_chen@foxmail.com>
pull/952/head
longxboy 4 years ago committed by GitHub
parent 66412031fd
commit eb958b2093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 164
      api/metadata/metadata.pb.go
  2. 2
      api/metadata/metadata_grpc.pb.go
  3. 95
      api/metadata/metadata_http.pb.go
  4. 12
      cmd/protoc-gen-go-http/http.go
  5. 46
      cmd/protoc-gen-go-http/template.go
  6. 42
      examples/helloworld/helloworld/helloworld_http.pb.go
  7. 4
      examples/http/handler/main.go
  8. 92
      examples/proto/echo_service.pb.go
  9. 1
      examples/proto/echo_service.proto
  10. 311
      examples/proto/echo_service_http.pb.go
  11. 11
      examples/proto/echo_service_test.go
  12. 13
      examples/proto/stream.pb.go
  13. 12
      examples/proto/stream_grpc.pb.go
  14. 4
      examples/proto/stream_http.pb.go
  15. 231
      transport/http/binding/encode.go
  16. 41
      transport/http/binding/proto.go
  17. 8
      transport/http/binding/proto_test.go
  18. 33
      transport/http/calloption.go
  19. 20
      transport/http/client.go
  20. 4
      transport/http/handle.go

@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.26.0
// protoc v3.14.0
// source: metadata.proto
// source: metadata/metadata.proto
package metadata
@ -31,7 +31,7 @@ type ListServicesRequest struct {
func (x *ListServicesRequest) Reset() {
*x = ListServicesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_metadata_proto_msgTypes[0]
mi := &file_metadata_metadata_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -44,7 +44,7 @@ func (x *ListServicesRequest) String() string {
func (*ListServicesRequest) ProtoMessage() {}
func (x *ListServicesRequest) ProtoReflect() protoreflect.Message {
mi := &file_metadata_proto_msgTypes[0]
mi := &file_metadata_metadata_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -57,7 +57,7 @@ func (x *ListServicesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListServicesRequest.ProtoReflect.Descriptor instead.
func (*ListServicesRequest) Descriptor() ([]byte, []int) {
return file_metadata_proto_rawDescGZIP(), []int{0}
return file_metadata_metadata_proto_rawDescGZIP(), []int{0}
}
type ListServicesReply struct {
@ -72,7 +72,7 @@ type ListServicesReply struct {
func (x *ListServicesReply) Reset() {
*x = ListServicesReply{}
if protoimpl.UnsafeEnabled {
mi := &file_metadata_proto_msgTypes[1]
mi := &file_metadata_metadata_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -85,7 +85,7 @@ func (x *ListServicesReply) String() string {
func (*ListServicesReply) ProtoMessage() {}
func (x *ListServicesReply) ProtoReflect() protoreflect.Message {
mi := &file_metadata_proto_msgTypes[1]
mi := &file_metadata_metadata_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -98,7 +98,7 @@ func (x *ListServicesReply) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListServicesReply.ProtoReflect.Descriptor instead.
func (*ListServicesReply) Descriptor() ([]byte, []int) {
return file_metadata_proto_rawDescGZIP(), []int{1}
return file_metadata_metadata_proto_rawDescGZIP(), []int{1}
}
func (x *ListServicesReply) GetServices() []string {
@ -126,7 +126,7 @@ type GetServiceDescRequest struct {
func (x *GetServiceDescRequest) Reset() {
*x = GetServiceDescRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_metadata_proto_msgTypes[2]
mi := &file_metadata_metadata_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -139,7 +139,7 @@ func (x *GetServiceDescRequest) String() string {
func (*GetServiceDescRequest) ProtoMessage() {}
func (x *GetServiceDescRequest) ProtoReflect() protoreflect.Message {
mi := &file_metadata_proto_msgTypes[2]
mi := &file_metadata_metadata_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -152,7 +152,7 @@ func (x *GetServiceDescRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetServiceDescRequest.ProtoReflect.Descriptor instead.
func (*GetServiceDescRequest) Descriptor() ([]byte, []int) {
return file_metadata_proto_rawDescGZIP(), []int{2}
return file_metadata_metadata_proto_rawDescGZIP(), []int{2}
}
func (x *GetServiceDescRequest) GetName() string {
@ -173,7 +173,7 @@ type GetServiceDescReply struct {
func (x *GetServiceDescReply) Reset() {
*x = GetServiceDescReply{}
if protoimpl.UnsafeEnabled {
mi := &file_metadata_proto_msgTypes[3]
mi := &file_metadata_metadata_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -186,7 +186,7 @@ func (x *GetServiceDescReply) String() string {
func (*GetServiceDescReply) ProtoMessage() {}
func (x *GetServiceDescReply) ProtoReflect() protoreflect.Message {
mi := &file_metadata_proto_msgTypes[3]
mi := &file_metadata_metadata_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -199,7 +199,7 @@ func (x *GetServiceDescReply) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetServiceDescReply.ProtoReflect.Descriptor instead.
func (*GetServiceDescReply) Descriptor() ([]byte, []int) {
return file_metadata_proto_rawDescGZIP(), []int{3}
return file_metadata_metadata_proto_rawDescGZIP(), []int{3}
}
func (x *GetServiceDescReply) GetFileDescSet() *descriptorpb.FileDescriptorSet {
@ -209,74 +209,74 @@ func (x *GetServiceDescReply) GetFileDescSet() *descriptorpb.FileDescriptorSet {
return nil
}
var File_metadata_proto protoreflect.FileDescriptor
var file_metadata_proto_rawDesc = []byte{
0x0a, 0x0e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x0a, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x15, 0x0a, 0x13,
0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0x2b,
0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5d, 0x0a, 0x13, 0x47,
0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x70,
0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x5f,
0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65,
0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x52, 0x0b, 0x66,
0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x53, 0x65, 0x74, 0x32, 0xdd, 0x01, 0x0a, 0x08, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x61, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12,
0x09, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x6e, 0x0a, 0x0e, 0x47, 0x65,
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x12, 0x21, 0x2e, 0x6b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1f, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42, 0x63, 0x0a, 0x15, 0x63, 0x6f,
0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e,
0x61, 0x70, 0x69, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x61, 0x74, 0x61, 0xa2, 0x02, 0x09, 0x4b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x41, 0x50, 0x49, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
var File_metadata_metadata_proto protoreflect.FileDescriptor
var file_metadata_metadata_proto_rawDesc = []byte{
0x0a, 0x17, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6b, 0x72, 0x61, 0x74, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x11,
0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c,
0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0x2b, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5d, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0d, 0x66,
0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63,
0x53, 0x65, 0x74, 0x32, 0xdd, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x12, 0x61, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
0x12, 0x1f, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1d, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x12, 0x6e, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x44, 0x65, 0x73, 0x63, 0x12, 0x21, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73,
0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x44, 0x65, 0x73, 0x63, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x12, 0x12, 0x10, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x6e, 0x61,
0x6d, 0x65, 0x7d, 0x42, 0x63, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x50, 0x01, 0x5a, 0x3c,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72,
0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
0x61, 0x70, 0x69, 0x3b, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xa2, 0x02, 0x09, 0x4b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_metadata_proto_rawDescOnce sync.Once
file_metadata_proto_rawDescData = file_metadata_proto_rawDesc
file_metadata_metadata_proto_rawDescOnce sync.Once
file_metadata_metadata_proto_rawDescData = file_metadata_metadata_proto_rawDesc
)
func file_metadata_proto_rawDescGZIP() []byte {
file_metadata_proto_rawDescOnce.Do(func() {
file_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_metadata_proto_rawDescData)
func file_metadata_metadata_proto_rawDescGZIP() []byte {
file_metadata_metadata_proto_rawDescOnce.Do(func() {
file_metadata_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_metadata_metadata_proto_rawDescData)
})
return file_metadata_proto_rawDescData
return file_metadata_metadata_proto_rawDescData
}
var file_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_metadata_proto_goTypes = []interface{}{
var file_metadata_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_metadata_metadata_proto_goTypes = []interface{}{
(*ListServicesRequest)(nil), // 0: kratos.api.ListServicesRequest
(*ListServicesReply)(nil), // 1: kratos.api.ListServicesReply
(*GetServiceDescRequest)(nil), // 2: kratos.api.GetServiceDescRequest
(*GetServiceDescReply)(nil), // 3: kratos.api.GetServiceDescReply
(*descriptorpb.FileDescriptorSet)(nil), // 4: google.protobuf.FileDescriptorSet
}
var file_metadata_proto_depIdxs = []int32{
var file_metadata_metadata_proto_depIdxs = []int32{
4, // 0: kratos.api.GetServiceDescReply.file_desc_set:type_name -> google.protobuf.FileDescriptorSet
0, // 1: kratos.api.Metadata.ListServices:input_type -> kratos.api.ListServicesRequest
2, // 2: kratos.api.Metadata.GetServiceDesc:input_type -> kratos.api.GetServiceDescRequest
@ -289,13 +289,13 @@ var file_metadata_proto_depIdxs = []int32{
0, // [0:1] is the sub-list for field type_name
}
func init() { file_metadata_proto_init() }
func file_metadata_proto_init() {
if File_metadata_proto != nil {
func init() { file_metadata_metadata_proto_init() }
func file_metadata_metadata_proto_init() {
if File_metadata_metadata_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
file_metadata_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListServicesRequest); i {
case 0:
return &v.state
@ -307,7 +307,7 @@ func file_metadata_proto_init() {
return nil
}
}
file_metadata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
file_metadata_metadata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListServicesReply); i {
case 0:
return &v.state
@ -319,7 +319,7 @@ func file_metadata_proto_init() {
return nil
}
}
file_metadata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
file_metadata_metadata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetServiceDescRequest); i {
case 0:
return &v.state
@ -331,7 +331,7 @@ func file_metadata_proto_init() {
return nil
}
}
file_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
file_metadata_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetServiceDescReply); i {
case 0:
return &v.state
@ -348,18 +348,18 @@ func file_metadata_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_metadata_proto_rawDesc,
RawDescriptor: file_metadata_metadata_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_metadata_proto_goTypes,
DependencyIndexes: file_metadata_proto_depIdxs,
MessageInfos: file_metadata_proto_msgTypes,
GoTypes: file_metadata_metadata_proto_goTypes,
DependencyIndexes: file_metadata_metadata_proto_depIdxs,
MessageInfos: file_metadata_metadata_proto_msgTypes,
}.Build()
File_metadata_proto = out.File
file_metadata_proto_rawDesc = nil
file_metadata_proto_goTypes = nil
file_metadata_proto_depIdxs = nil
File_metadata_metadata_proto = out.File
file_metadata_metadata_proto_rawDesc = nil
file_metadata_metadata_proto_goTypes = nil
file_metadata_metadata_proto_depIdxs = nil
}

@ -137,5 +137,5 @@ var Metadata_ServiceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
Metadata: "metadata.proto",
Metadata: "metadata/metadata.proto",
}

@ -26,11 +26,102 @@ type MetadataHandler interface {
}
func NewMetadataHandler(srv MetadataHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
r.Handle("/services", http1.NewHandler(srv.ListServices, opts...)).Methods("GET")
r.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
var in ListServicesRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
r.Handle("/services/{name}", http1.NewHandler(srv.GetServiceDesc, opts...)).Methods("GET")
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.ListServices(ctx, req.(*ListServicesRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*ListServicesReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/services/{name}", func(w http.ResponseWriter, r *http.Request) {
var in GetServiceDescRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetServiceDesc(ctx, req.(*GetServiceDescRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*GetServiceDescReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
}
type MetadataHttpClient interface {
GetServiceDesc(ctx context.Context, req *GetServiceDescRequest, opts ...http1.CallOption) (rsp *GetServiceDescReply, err error)
ListServices(ctx context.Context, req *ListServicesRequest, opts ...http1.CallOption) (rsp *ListServicesReply, err error)
}
type MetadataHttpClientImpl struct {
cc *http1.Client
}
func NewMetadataHttpClient(client *http1.Client) MetadataHttpClient {
return &MetadataHttpClientImpl{client}
}
func (c *MetadataHttpClientImpl) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest, opts ...http1.CallOption) (out *GetServiceDescReply, err error) {
path := binding.EncodePath("GET", "/services/{name}", in)
out = &GetServiceDescReply{}
err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/services/{name}"))
if err != nil {
return
}
return
}
func (c *MetadataHttpClientImpl) ListServices(ctx context.Context, in *ListServicesRequest, opts ...http1.CallOption) (out *ListServicesReply, err error) {
path := binding.EncodePath("GET", "/services", in)
out = &ListServicesReply{}
err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/services"))
if err != nil {
return
}
return
}

@ -114,14 +114,18 @@ func buildHTTPRule(g *protogen.GeneratedFile, m *protogen.Method, rule *annotati
responseBody = rule.ResponseBody
md := buildMethodDesc(g, m, method, path)
if body == "*" {
md.Body = "*"
md.HasBody = true
md.Body = ""
} else if body != "" {
md.Body = "." + body
md.HasBody = true
md.Body = "." + camelCaseVars(body)
} else {
md.HasBody = false
}
if responseBody == "*" {
md.ResponseBody = "*"
md.ResponseBody = ""
} else if responseBody != "" {
md.ResponseBody = "." + responseBody
md.ResponseBody = "." + camelCaseVars(responseBody)
}
return md
}

@ -14,9 +14,40 @@ type {{.ServiceType}}Handler interface {
}
func New{{.ServiceType}}Handler(srv {{.ServiceType}}Handler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
{{range .Methods}}
r.Handle("{{.Path}}", http1.NewHandler(srv.{{.Name}}, opts...)).Methods("{{.Method}}")
r.HandleFunc("{{.Path}}", func(w http.ResponseWriter, r *http.Request) {
var in {{.Request}}
if err := h.Decode(r, &in{{.Body}}); err != nil {
h.Error(w, r, err)
return
}
{{if ne (len .Vars) 0}}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
{{end}}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.{{.Name}}(ctx, req.(*{{.Request}}))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*{{.Reply}})
if err := h.Encode(w, r, reply{{.ResponseBody}}); err != nil {
h.Error(w, r, err)
}
}).Methods("{{.Method}}")
{{end}}
return r
}
@ -39,12 +70,13 @@ func New{{.ServiceType}}HttpClient (client *http1.Client) {{.ServiceType}}HttpCl
{{$svrName := .ServiceName}}
{{range .MethodSets}}
func (c *{{$svrType}}HttpClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http1.CallOption) (out *{{.Reply}}, err error) {
path := "{{.Path}}"
method := "{{.Method}}"
body := "{{.Body}}"
path := binding.EncodePath("{{.Method}}", "{{.Path}}", in)
out = &{{.Reply}}{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
{{if .HasBody }}
err = c.cc.Invoke(ctx, path, in{{.Body}}, &out{{.ResponseBody}}, http1.Method("{{.Method}}"), http1.PathPattern("{{.Path}}"))
{{else}}
err = c.cc.Invoke(ctx, path, nil, &out{{.ResponseBody}}, http1.Method("{{.Method}}"), http1.PathPattern("{{.Path}}"))
{{end}}
if err != nil {
return
}
@ -66,12 +98,12 @@ type methodDesc struct {
Name string
Num int
Vars []string
Forms []string
Request string
Reply string
// http_rule
Path string
Method string
HasBody bool
Body string
ResponseBody string
}

@ -24,9 +24,40 @@ type GreeterHandler interface {
}
func NewGreeterHandler(srv GreeterHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
r.Handle("/helloworld/{name}", http1.NewHandler(srv.SayHello, opts...)).Methods("GET")
r.HandleFunc("/helloworld/{name}", func(w http.ResponseWriter, r *http.Request) {
var in HelloRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SayHello(ctx, req.(*HelloRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*HelloReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
}
@ -44,12 +75,11 @@ func NewGreeterHttpClient(client *http1.Client) GreeterHttpClient {
}
func (c *GreeterHttpClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http1.CallOption) (out *HelloReply, err error) {
path := "/helloworld/{name}"
method := "GET"
body := ""
path := binding.EncodePath("GET", "/helloworld/{name}", in)
out = &HelloReply{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/helloworld/{name}"))
if err != nil {
return
}

@ -34,8 +34,8 @@ func main() {
users: make(map[string]*User),
}
router := mux.NewRouter()
router.Handle("/users", http.NewHandler(us.Add)).Methods("POST")
router.Handle("/users/{id}", http.NewHandler(us.Get)).Methods("GET")
router.Handle("/users/add", http.NewHandler(us.Add)).Methods("POST")
router.Handle("/users/detail", http.NewHandler(us.Get)).Methods("GET")
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", router)

@ -1,18 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// protoc-gen-go v1.26.0
// protoc v3.14.0
// source: echo_service.proto
package testproto
import (
proto "github.com/golang/protobuf/proto"
_struct "github.com/golang/protobuf/ptypes/struct"
_ "google.golang.org/genproto/googleapis/api/annotations"
field_mask "google.golang.org/genproto/protobuf/field_mask"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
structpb "google.golang.org/protobuf/types/known/structpb"
reflect "reflect"
sync "sync"
)
@ -24,10 +23,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Corpus int32
const (
@ -332,8 +327,8 @@ type DynamicMessage struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
StructField *_struct.Struct `protobuf:"bytes,1,opt,name=struct_field,json=structField,proto3" json:"struct_field,omitempty"`
ValueField *_struct.Value `protobuf:"bytes,2,opt,name=value_field,json=valueField,proto3" json:"value_field,omitempty"`
StructField *structpb.Struct `protobuf:"bytes,1,opt,name=struct_field,json=structField,proto3" json:"struct_field,omitempty"`
ValueField *structpb.Value `protobuf:"bytes,2,opt,name=value_field,json=valueField,proto3" json:"value_field,omitempty"`
}
func (x *DynamicMessage) Reset() {
@ -368,14 +363,14 @@ func (*DynamicMessage) Descriptor() ([]byte, []int) {
return file_echo_service_proto_rawDescGZIP(), []int{2}
}
func (x *DynamicMessage) GetStructField() *_struct.Struct {
func (x *DynamicMessage) GetStructField() *structpb.Struct {
if x != nil {
return x.StructField
}
return nil
}
func (x *DynamicMessage) GetValueField() *_struct.Value {
func (x *DynamicMessage) GetValueField() *structpb.Value {
if x != nil {
return x.ValueField
}
@ -387,8 +382,8 @@ type DynamicMessageUpdate struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Body *DynamicMessage `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"`
UpdateMask *field_mask.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
Body *DynamicMessage `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"`
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
}
func (x *DynamicMessageUpdate) Reset() {
@ -430,7 +425,7 @@ func (x *DynamicMessageUpdate) GetBody() *DynamicMessage {
return nil
}
func (x *DynamicMessageUpdate) GetUpdateMask() *field_mask.FieldMask {
func (x *DynamicMessageUpdate) GetUpdateMask() *fieldmaskpb.FieldMask {
if x != nil {
return x.UpdateMask
}
@ -491,7 +486,7 @@ var file_echo_service_proto_rawDesc = []byte{
0x4d, 0x41, 0x47, 0x45, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c,
0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x45, 0x57, 0x53, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08,
0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x53, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49,
0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xcc, 0x05, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65,
0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xcf, 0x05, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xf2, 0x01, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x18,
0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c,
0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
@ -513,35 +508,36 @@ var file_echo_service_proto_rawDesc = []byte{
0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d,
0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x1a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x82, 0x01, 0x0a,
0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x85, 0x01, 0x0a,
0x10, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64,
0x79, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79,
0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44,
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x1e, 0x2f, 0x76, 0x31,
0x61, 0x74, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31,
0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x72, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x62, 0x04, 0x62, 0x6f, 0x64,
0x79, 0x12, 0x6c, 0x0a, 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70,
0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x76, 0x31,
0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x64, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x12,
0x73, 0x0a, 0x09, 0x45, 0x63, 0x68, 0x6f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x74,
0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x1f, 0x2e,
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69,
0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x24,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x04,
0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61,
0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67,
0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65,
0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x62, 0x04,
0x62, 0x6f, 0x64, 0x79, 0x12, 0x6c, 0x0a, 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74,
0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22,
0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f,
0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75,
0x6d, 0x7d, 0x12, 0x73, 0x0a, 0x09, 0x45, 0x63, 0x68, 0x6f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12,
0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61,
0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e,
0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65,
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63,
0x68, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
@ -559,14 +555,14 @@ func file_echo_service_proto_rawDescGZIP() []byte {
var file_echo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_echo_service_proto_goTypes = []interface{}{
(Corpus)(0), // 0: testproto.Corpus
(*Embedded)(nil), // 1: testproto.Embedded
(*SimpleMessage)(nil), // 2: testproto.SimpleMessage
(*DynamicMessage)(nil), // 3: testproto.DynamicMessage
(*DynamicMessageUpdate)(nil), // 4: testproto.DynamicMessageUpdate
(*_struct.Struct)(nil), // 5: google.protobuf.Struct
(*_struct.Value)(nil), // 6: google.protobuf.Value
(*field_mask.FieldMask)(nil), // 7: google.protobuf.FieldMask
(Corpus)(0), // 0: testproto.Corpus
(*Embedded)(nil), // 1: testproto.Embedded
(*SimpleMessage)(nil), // 2: testproto.SimpleMessage
(*DynamicMessage)(nil), // 3: testproto.DynamicMessage
(*DynamicMessageUpdate)(nil), // 4: testproto.DynamicMessageUpdate
(*structpb.Struct)(nil), // 5: google.protobuf.Struct
(*structpb.Value)(nil), // 6: google.protobuf.Value
(*fieldmaskpb.FieldMask)(nil), // 7: google.protobuf.FieldMask
}
var file_echo_service_proto_depIdxs = []int32{
1, // 0: testproto.SimpleMessage.status:type_name -> testproto.Embedded

@ -89,6 +89,7 @@ service EchoService {
rpc EchoResponseBody(DynamicMessageUpdate) returns (DynamicMessageUpdate) {
option (google.api.http) = {
post: "/v1/example/echo_response_body"
body: "*"
response_body: "body"
};
}

@ -32,25 +32,257 @@ type EchoServiceHandler interface {
}
func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
r.Handle("/v1/example/echo/{id}/{num}", http1.NewHandler(srv.Echo, opts...)).Methods("GET")
r.Handle("/v1/example/echo/{id}/{num}/{lang}", http1.NewHandler(srv.Echo, opts...)).Methods("GET")
r.Handle("/v1/example/echo1/{id}/{line_num}/{status.note}", http1.NewHandler(srv.Echo, opts...)).Methods("GET")
r.Handle("/v1/example/echo2/{no.note}", http1.NewHandler(srv.Echo, opts...)).Methods("GET")
r.Handle("/v1/example/echo/{id}", http1.NewHandler(srv.Echo, opts...)).Methods("POST")
r.Handle("/v1/example/echo_body", http1.NewHandler(srv.EchoBody, opts...)).Methods("POST")
r.Handle("/v1/example/echo_response_body", http1.NewHandler(srv.EchoResponseBody, opts...)).Methods("POST")
r.Handle("/v1/example/echo_delete/{id}/{num}", http1.NewHandler(srv.EchoDelete, opts...)).Methods("DELETE")
r.Handle("/v1/example/echo_patch", http1.NewHandler(srv.EchoPatch, opts...)).Methods("PATCH")
r.HandleFunc("/v1/example/echo/{id}/{num}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/v1/example/echo/{id}/{num}/{lang}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/v1/example/echo1/{id}/{line_num}/{status.note}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/v1/example/echo2/{no.note}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
r.HandleFunc("/v1/example/echo/{id}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
r.HandleFunc("/v1/example/echo_body", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoBody(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
r.HandleFunc("/v1/example/echo_response_body", func(w http.ResponseWriter, r *http.Request) {
var in DynamicMessageUpdate
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoResponseBody(ctx, req.(*DynamicMessageUpdate))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*DynamicMessageUpdate)
if err := h.Encode(w, r, reply.Body); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
r.HandleFunc("/v1/example/echo_delete/{id}/{num}", func(w http.ResponseWriter, r *http.Request) {
var in SimpleMessage
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoDelete(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("DELETE")
r.HandleFunc("/v1/example/echo_patch", func(w http.ResponseWriter, r *http.Request) {
var in DynamicMessageUpdate
if err := h.Decode(r, &in.Body); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoPatch(ctx, req.(*DynamicMessageUpdate))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
out, err := next(r.Context(), &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*DynamicMessageUpdate)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("PATCH")
return r
}
@ -76,12 +308,11 @@ func NewEchoServiceHttpClient(client *http1.Client) EchoServiceHttpClient {
}
func (c *EchoServiceHttpClientImpl) Echo(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
path := "/v1/example/echo/{id}"
method := "POST"
body := ""
path := binding.EncodePath("POST", "/v1/example/echo/{id}", in)
out = &SimpleMessage{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("POST"), http1.PathPattern("/v1/example/echo/{id}"))
if err != nil {
return
}
@ -89,12 +320,11 @@ func (c *EchoServiceHttpClientImpl) Echo(ctx context.Context, in *SimpleMessage,
}
func (c *EchoServiceHttpClientImpl) EchoBody(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
path := "/v1/example/echo_body"
method := "POST"
body := "*"
path := binding.EncodePath("POST", "/v1/example/echo_body", in)
out = &SimpleMessage{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, in, &out, http1.Method("POST"), http1.PathPattern("/v1/example/echo_body"))
if err != nil {
return
}
@ -102,12 +332,11 @@ func (c *EchoServiceHttpClientImpl) EchoBody(ctx context.Context, in *SimpleMess
}
func (c *EchoServiceHttpClientImpl) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
path := "/v1/example/echo_delete/{id}/{num}"
method := "DELETE"
body := ""
path := binding.EncodePath("DELETE", "/v1/example/echo_delete/{id}/{num}", in)
out = &SimpleMessage{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("DELETE"), http1.PathPattern("/v1/example/echo_delete/{id}/{num}"))
if err != nil {
return
}
@ -115,12 +344,11 @@ func (c *EchoServiceHttpClientImpl) EchoDelete(ctx context.Context, in *SimpleMe
}
func (c *EchoServiceHttpClientImpl) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (out *DynamicMessageUpdate, err error) {
path := "/v1/example/echo_patch"
method := "PATCH"
body := ".body"
path := binding.EncodePath("PATCH", "/v1/example/echo_patch", in)
out = &DynamicMessageUpdate{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, in.Body, &out, http1.Method("PATCH"), http1.PathPattern("/v1/example/echo_patch"))
if err != nil {
return
}
@ -128,12 +356,11 @@ func (c *EchoServiceHttpClientImpl) EchoPatch(ctx context.Context, in *DynamicMe
}
func (c *EchoServiceHttpClientImpl) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (out *DynamicMessageUpdate, err error) {
path := "/v1/example/echo_response_body"
method := "POST"
body := ""
path := binding.EncodePath("POST", "/v1/example/echo_response_body", in)
out = &DynamicMessageUpdate{}
err = c.cc.Invoke(ctx, path, in, out, http1.BodyPattern(body), http1.Method(method))
err = c.cc.Invoke(ctx, path, in, &out.Body, http1.Method("POST"), http1.PathPattern("/v1/example/echo_response_body"))
if err != nil {
return
}

@ -119,17 +119,20 @@ func testEchoClient(t *testing.T, addr string) {
}}
dout *DynamicMessageUpdate
)
if dout, err = cli.EchoPatch(context.Background(), din); err != nil {
if dout, err = cli.EchoResponseBody(context.Background(), din); err != nil {
t.Fatal(err)
}
if din.Body.ValueField.GetStringValue() != dout.Body.ValueField.GetStringValue() {
t.Errorf("EchoPatch expected %s got %s", din, dout)
t.Fatalf("EchoResponseBody expected %s got %s", din, dout)
}
if dout, err = cli.EchoResponseBody(context.Background(), din); err != nil {
if dout, err = cli.EchoPatch(context.Background(), din); err != nil {
t.Fatal(err)
}
if dout.Body == nil {
panic("dout.body is nil")
}
if din.Body.ValueField.GetStringValue() != dout.Body.ValueField.GetStringValue() {
t.Errorf("EchoResponseBody expected %s got %s", din, dout)
t.Fatalf("EchoPatch expected %s got %s", din, dout)
}
}

@ -1,18 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.13.0
// protoc-gen-go v1.26.0
// protoc v3.14.0
// source: stream.proto
package testproto
import (
proto "github.com/golang/protobuf/proto"
empty "github.com/golang/protobuf/ptypes/empty"
_ "google.golang.org/genproto/googleapis/api/annotations"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
)
@ -23,10 +22,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
var File_stream_proto protoreflect.FileDescriptor
var file_stream_proto_rawDesc = []byte{
@ -53,7 +48,7 @@ var file_stream_proto_rawDesc = []byte{
}
var file_stream_proto_goTypes = []interface{}{
(*empty.Empty)(nil), // 0: google.protobuf.Empty
(*emptypb.Empty)(nil), // 0: google.protobuf.Empty
(*httpbody.HttpBody)(nil), // 1: google.api.HttpBody
}
var file_stream_proto_depIdxs = []int32{

@ -4,11 +4,11 @@ package testproto
import (
context "context"
empty "github.com/golang/protobuf/ptypes/empty"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
@ -20,7 +20,7 @@ const _ = grpc.SupportPackageIsVersion7
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type StreamServiceClient interface {
Download(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (StreamService_DownloadClient, error)
Download(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (StreamService_DownloadClient, error)
}
type streamServiceClient struct {
@ -31,7 +31,7 @@ func NewStreamServiceClient(cc grpc.ClientConnInterface) StreamServiceClient {
return &streamServiceClient{cc}
}
func (c *streamServiceClient) Download(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (StreamService_DownloadClient, error) {
func (c *streamServiceClient) Download(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (StreamService_DownloadClient, error) {
stream, err := c.cc.NewStream(ctx, &StreamService_ServiceDesc.Streams[0], "/testproto.StreamService/Download", opts...)
if err != nil {
return nil, err
@ -67,7 +67,7 @@ func (x *streamServiceDownloadClient) Recv() (*httpbody.HttpBody, error) {
// All implementations must embed UnimplementedStreamServiceServer
// for forward compatibility
type StreamServiceServer interface {
Download(*empty.Empty, StreamService_DownloadServer) error
Download(*emptypb.Empty, StreamService_DownloadServer) error
mustEmbedUnimplementedStreamServiceServer()
}
@ -75,7 +75,7 @@ type StreamServiceServer interface {
type UnimplementedStreamServiceServer struct {
}
func (UnimplementedStreamServiceServer) Download(*empty.Empty, StreamService_DownloadServer) error {
func (UnimplementedStreamServiceServer) Download(*emptypb.Empty, StreamService_DownloadServer) error {
return status.Errorf(codes.Unimplemented, "method Download not implemented")
}
func (UnimplementedStreamServiceServer) mustEmbedUnimplementedStreamServiceServer() {}
@ -92,7 +92,7 @@ func RegisterStreamServiceServer(s grpc.ServiceRegistrar, srv StreamServiceServe
}
func _StreamService_Download_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(empty.Empty)
m := new(emptypb.Empty)
if err := stream.RecvMsg(m); err != nil {
return err
}

@ -23,6 +23,10 @@ type StreamServiceHandler interface {
}
func NewStreamServiceHandler(srv StreamServiceHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
return r

@ -0,0 +1,231 @@
package binding
import (
"encoding/base64"
"fmt"
"net/url"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
// EncodePath binds proto message to url path
func EncodePath(method string, pathPattern string, msg proto.Message) string {
if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
return pathPattern
}
reg := regexp.MustCompile(`/{[.\w]+}`)
if reg == nil {
return pathPattern
}
pathParams := make(map[string]struct{}, 0)
path := reg.ReplaceAllStringFunc(pathPattern, func(in string) string {
if len(in) < 4 {
return in
}
key := in[2 : len(in)-1]
vars := strings.Split(key, ".")
if value, err := getValueByField(msg.ProtoReflect(), vars); err == nil {
pathParams[key] = struct{}{}
return "/" + value
}
return in
})
if method == "GET" {
u, err := encodeQuery(msg)
if err == nil && len(u) > 0 {
for key := range pathParams {
delete(u, key)
}
query := u.Encode()
if query != "" {
path += "?" + query
}
}
}
return path
}
func getValueByField(v protoreflect.Message, fieldPath []string) (string, error) {
var fd protoreflect.FieldDescriptor
for i, fieldName := range fieldPath {
fields := v.Descriptor().Fields()
if fd = fields.ByName(protoreflect.Name(fieldName)); fd == nil {
fd = fields.ByJSONName(fieldName)
if fd == nil {
return "", fmt.Errorf("field path not found: %q", fieldName)
}
}
if i == len(fieldPath)-1 {
break
}
if fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {
return "", fmt.Errorf("invalid path: %q is not a message", fieldName)
}
v = v.Get(fd).Message()
}
return encodeField(fd, v.Get(fd))
}
func encodeQuery(msg proto.Message) (url.Values, error) {
if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
return url.Values{}, nil
}
u := make(url.Values)
err := encodeByField(u, "", msg.ProtoReflect())
if err != nil {
return nil, err
}
return u, nil
}
func encodeByField(u url.Values, path string, v protoreflect.Message) error {
for i := 0; i < v.Descriptor().Fields().Len(); i++ {
fd := v.Descriptor().Fields().Get(i)
var key string = fd.TextName()
var newPath string
if path == "" {
newPath = key
} else {
newPath = path + "." + key
}
if fd.HasJSONName() {
key = fd.JSONName()
}
switch {
case fd.IsList():
list, err := encodeRepeatedField(fd, v.Get(fd).List())
if err != nil {
return err
}
u[newPath] = list
case fd.IsMap():
m, err := encodeMapField(fd, v.Get(fd).Map())
if err != nil {
return err
}
for k, value := range m {
u[fmt.Sprintf("%s[%s]", newPath, k)] = []string{value}
}
case (fd.Kind() == protoreflect.MessageKind) || (fd.Kind() == protoreflect.GroupKind):
value, err := encodeMessage(fd.Message(), v.Get(fd))
if err == nil {
u[newPath] = []string{value}
return nil
}
return encodeByField(u, newPath, v.Get(fd).Message())
default:
value, err := encodeField(fd, v.Get(fd))
if err != nil {
return err
}
u[newPath] = []string{value}
}
}
return nil
}
func encodeMessageField(fieldDescriptor protoreflect.FieldDescriptor, msgValue protoreflect.Message) (string, error) {
return encodeField(fieldDescriptor, msgValue.Get(fieldDescriptor))
}
func encodeRepeatedField(fieldDescriptor protoreflect.FieldDescriptor, list protoreflect.List) ([]string, error) {
var values []string
for i := 0; i < list.Len(); i++ {
value, err := encodeField(fieldDescriptor, list.Get(i))
if err != nil {
return nil, err
}
values = append(values, value)
}
return values, nil
}
func encodeMapField(fieldDescriptor protoreflect.FieldDescriptor, mp protoreflect.Map) (map[string]string, error) {
m := make(map[string]string)
mp.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
key, err := encodeField(fieldDescriptor.MapValue(), k.Value())
if err != nil {
return false
}
value, err := encodeField(fieldDescriptor.MapValue(), v)
if err != nil {
return false
}
m[key] = value
return true
})
return m, nil
}
func encodeField(fieldDescriptor protoreflect.FieldDescriptor, value protoreflect.Value) (string, error) {
switch fieldDescriptor.Kind() {
case protoreflect.BoolKind:
return strconv.FormatBool(value.Bool()), nil
case protoreflect.EnumKind:
if fieldDescriptor.Enum().FullName() == "google.protobuf.NullValue" {
return "null", nil
}
desc := fieldDescriptor.Enum().Values().ByNumber(value.Enum())
return string(desc.Name()), nil
case protoreflect.StringKind:
return value.String(), nil
case protoreflect.BytesKind:
return base64.URLEncoding.EncodeToString(value.Bytes()), nil
case protoreflect.MessageKind, protoreflect.GroupKind:
return encodeMessage(fieldDescriptor.Message(), value)
default:
return fmt.Sprintf("%v", value.Interface()), nil
}
}
// marshalMessage marshals the fields in the given protoreflect.Message.
// If the typeURL is non-empty, then a synthetic "@type" field is injected
// containing the URL as the value.
func encodeMessage(msgDescriptor protoreflect.MessageDescriptor, value protoreflect.Value) (string, error) {
switch msgDescriptor.FullName() {
case "google.protobuf.Timestamp":
t, ok := value.Interface().(*timestamppb.Timestamp)
if !ok {
return "", nil
}
return t.AsTime().Format(time.RFC3339Nano), nil
case "google.protobuf.Duration":
d, ok := value.Interface().(*durationpb.Duration)
if !ok {
return "", nil
}
return d.AsDuration().String(), nil
case "google.protobuf.BytesValue":
b, ok := value.Interface().(*wrapperspb.BytesValue)
if !ok {
return "", nil
}
return base64.StdEncoding.EncodeToString(b.Value), nil
case "google.protobuf.DoubleValue", "google.protobuf.FloatValue", "google.protobuf.Int64Value", "google.protobuf.Int32Value",
"google.protobuf.UInt64Value", "google.protobuf.UInt32Value", "google.protobuf.BoolValue", "google.protobuf.StringValue":
fd := msgDescriptor.Fields()
v := value.Message().Get(fd.ByName(protoreflect.Name("value"))).Message()
return fmt.Sprintf("%v", v.Interface()), nil
case "google.protobuf.FieldMask":
m, ok := value.Interface().(*field_mask.FieldMask)
if !ok {
return "", nil
}
return strings.Join(m.Paths, ","), nil
default:
return "", fmt.Errorf("unsupported message type: %q", string(msgDescriptor.FullName()))
}
}

@ -4,7 +4,6 @@ import (
"encoding/base64"
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"time"
@ -18,46 +17,6 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
)
// ProtoPath binds proto message to url path
func ProtoPath(template string, msg proto.Message) string {
reg := regexp.MustCompile(`/{[.\w]+}`)
if reg == nil {
return template
}
return reg.ReplaceAllStringFunc(template, func(in string) string {
if len(in) < 4 {
return in
}
str := in[2 : len(in)-1]
vars := strings.Split(str, ".")
if value, err := getValueByField(msg.ProtoReflect(), vars); err == nil {
return "/" + value
}
return in
})
}
func getValueByField(v protoreflect.Message, fieldPath []string) (string, error) {
var fd protoreflect.FieldDescriptor
for i, fieldName := range fieldPath {
fields := v.Descriptor().Fields()
if fd = fields.ByName(protoreflect.Name(fieldName)); fd == nil {
fd = fields.ByJSONName(fieldName)
if fd == nil {
return "", fmt.Errorf("field path not found: %q", fieldName)
}
}
if i == len(fieldPath)-1 {
break
}
if fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {
return "", fmt.Errorf("invalid path: %q is not a message", fieldName)
}
v = v.Mutable(fd).Message()
}
return fmt.Sprintf("%v", v.Get(fd).Interface()), nil
}
// MapProto sets a value in a nested Protobuf structure.
// Deprecated: use BindValue instead.
func MapProto(msg proto.Message, values map[string]string) error {

@ -6,25 +6,25 @@ import (
)
func TestProtoPath(t *testing.T) {
url := ProtoPath("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
url := EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/2233!!!` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = ProtoPath("http://helloworld.Greeter/helloworld/sub", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/sub", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/sub` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = ProtoPath("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test"})
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test"})
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = ProtoPath("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &HelloRequest{Name: "test"})
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &HelloRequest{Name: "test"})
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/{sub.name33}` {
t.Fatalf("proto path not expected!actual: %s ", url)

@ -12,6 +12,11 @@ type CallOption interface {
after(*callInfo, *csAttempt)
}
type callInfo struct {
pathPattern string
method string
}
// EmptyCallOption does not alter the Call configuration.
// It can be embedded in another structure to carry satellite data for use
// by interceptors.
@ -20,28 +25,23 @@ type EmptyCallOption struct{}
func (EmptyCallOption) before(*callInfo) error { return nil }
func (EmptyCallOption) after(*callInfo, *csAttempt) {}
type callInfo struct {
bodyPattern string
method string
}
type csAttempt struct{}
// BodyPattern is bodyPattern
func BodyPattern(bodyPattern string) CallOption {
return BodyPatternCallOption{BodyPattern: bodyPattern}
// PathPattern is pathpattern
func PathPattern(pathPattern string) CallOption {
return PathPatternCallOption{PathPattern: pathPattern}
}
// BodyPatternCallOption is BodyPattern
type BodyPatternCallOption struct {
BodyPattern string
// PathPatternCallOption is BodyPattern
type PathPatternCallOption struct {
EmptyCallOption
PathPattern string
}
func (o BodyPatternCallOption) before(c *callInfo) error {
c.bodyPattern = o.BodyPattern
func (o PathPatternCallOption) before(c *callInfo) error {
c.pathPattern = o.PathPattern
return nil
}
func (o BodyPatternCallOption) after(c *callInfo, attempt *csAttempt) {}
// Method is Method
func Method(method string) CallOption {
@ -50,6 +50,7 @@ func Method(method string) CallOption {
// MethodCallOption is BodyCallOption
type MethodCallOption struct {
EmptyCallOption
Method string
}
@ -57,11 +58,9 @@ func (o MethodCallOption) before(c *callInfo) error {
c.method = o.Method
return nil
}
func (o MethodCallOption) after(c *callInfo, attempt *csAttempt) {}
func defaultCallInfo() callInfo {
return callInfo{
bodyPattern: "*",
method: "POST",
method: "POST",
}
}

@ -14,8 +14,6 @@ import (
"github.com/go-kratos/kratos/v2/internal/httputil"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
"github.com/go-kratos/kratos/v2/transport/http/binding"
"google.golang.org/protobuf/proto"
)
// Client is http client
@ -147,7 +145,7 @@ func NewClient(ctx context.Context, opts ...ClientOption) (*Client, error) {
}
// Invoke makes an rpc call procedure for remote service.
func (client *Client) Invoke(ctx context.Context, pathPattern string, args interface{}, reply interface{}, opts ...CallOption) error {
func (client *Client) Invoke(ctx context.Context, path string, args interface{}, reply interface{}, opts ...CallOption) error {
var (
reqBody io.Reader
contentType string
@ -160,14 +158,7 @@ func (client *Client) Invoke(ctx context.Context, pathPattern string, args inter
}
}
path := pathPattern
if args != nil {
// TODO: support for struct path bindings
path = binding.ProtoPath(path, args.(proto.Message))
}
url := fmt.Sprintf("%s://%s%s", client.schema, client.endpoint, path)
if args != nil && c.bodyPattern != "" {
// TODO: only encode the target field of args
var (
body []byte
err error
@ -178,20 +169,21 @@ func (client *Client) Invoke(ctx context.Context, pathPattern string, args inter
}
reqBody = bytes.NewReader(body)
}
url := fmt.Sprintf("%s://%s%s", client.schema, client.endpoint, path)
req, err := http.NewRequest(c.method, url, reqBody)
if err != nil {
return err
}
if client.userAgent != "" {
req.Header.Set("User-Agent", client.userAgent)
}
if contentType != "" {
req.Header.Set("Content-Type", contentType)
}
if client.userAgent != "" {
req.Header.Set("User-Agent", client.userAgent)
}
ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindHTTP})
ctx = NewClientContext(ctx, ClientInfo{
PathPattern: pathPattern,
PathPattern: c.pathPattern,
Request: req,
})

@ -13,7 +13,6 @@ import (
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/transport/http/binding"
"github.com/gorilla/mux"
)
// SupportPackageIsVersion1 These constants should not be referenced from any other code.
@ -167,9 +166,6 @@ func defaultRequestDecoder(req *http.Request, v interface{}) error {
return errors.BadRequest("CODEC", err.Error())
}
}
if err := binding.BindVars(mux.Vars(req), v); err != nil {
return errors.BadRequest("CODEC", err.Error())
}
return nil
}

Loading…
Cancel
Save