From ac4c5281c4b04f9290c7143f5ba929c875f2425d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=86=8A=E9=97=AF?= Date: Fri, 31 Mar 2023 18:24:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=B0=E5=9D=80=E6=A0=8F?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- encoding/form/proto_encode.go | 26 ++++++++++++++++++++++---- transport/http/binding/encode.go | 7 ++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/encoding/form/proto_encode.go b/encoding/form/proto_encode.go index 550648dcf..354bfa7c2 100644 --- a/encoding/form/proto_encode.go +++ b/encoding/form/proto_encode.go @@ -20,7 +20,7 @@ func EncodeValues(msg interface{}) (url.Values, error) { } if v, ok := msg.(proto.Message); ok { u := make(url.Values) - err := encodeByField(u, "", v.ProtoReflect()) + err := encodeByField(u, "", v.ProtoReflect(), false) if err != nil { return nil, err } @@ -29,13 +29,31 @@ func EncodeValues(msg interface{}) (url.Values, error) { return encoder.Encode(msg) } -func encodeByField(u url.Values, path string, m protoreflect.Message) (finalErr error) { +// EncodeTextNameValues encode a message into url values. +func EncodeTextNameValues(msg interface{}) (url.Values, error) { + if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) { + return url.Values{}, nil + } + if v, ok := msg.(proto.Message); ok { + u := make(url.Values) + err := encodeByField(u, "", v.ProtoReflect(), true) + if err != nil { + return nil, err + } + return u, nil + } + return encoder.Encode(msg) +} + +func encodeByField(u url.Values, path string, m protoreflect.Message, forceTextName bool) (finalErr error) { m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { var ( key string newPath string ) - if fd.HasJSONName() { + if forceTextName { + key = fd.TextName() + } else if fd.HasJSONName() { key = fd.JSONName() } else { key = fd.TextName() @@ -79,7 +97,7 @@ func encodeByField(u url.Values, path string, m protoreflect.Message) (finalErr u.Set(newPath, value) return true } - if err = encodeByField(u, newPath, v.Message()); err != nil { + if err = encodeByField(u, newPath, v.Message(), forceTextName); err != nil { finalErr = err return false } diff --git a/transport/http/binding/encode.go b/transport/http/binding/encode.go index 5f12cf370..047d12ec7 100644 --- a/transport/http/binding/encode.go +++ b/transport/http/binding/encode.go @@ -17,6 +17,7 @@ func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string { return pathTemplate } queryParams, _ := form.EncodeValues(msg) + textNameQueryParams, _ := form.EncodeTextNameValues(msg) pathParams := make(map[string]struct{}) path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string { // it's unreachable because the reg means that must have more than one char in {} @@ -25,7 +26,11 @@ func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string { // } key := in[1 : len(in)-1] pathParams[key] = struct{}{} - return queryParams.Get(key) + value := queryParams.Get(key) + if len(value) > 0 { + return value + } + return textNameQueryParams.Get(key) }) if !needQuery { if v, ok := msg.(proto.Message); ok {