github.com/hduhelp/go-zero@v1.4.3/gateway/internal/requestparser.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io" 7 "net/http" 8 9 "github.com/fullstorydev/grpcurl" 10 "github.com/golang/protobuf/jsonpb" 11 "github.com/hduhelp/go-zero/rest/httpx" 12 "github.com/hduhelp/go-zero/rest/pathvar" 13 ) 14 15 // NewRequestParser creates a new request parser from the given http.Request and resolver. 16 func NewRequestParser(r *http.Request, resolver jsonpb.AnyResolver) (grpcurl.RequestParser, error) { 17 vars := pathvar.Vars(r) 18 params, err := httpx.GetFormValues(r) 19 if err != nil { 20 return nil, err 21 } 22 23 for k, v := range vars { 24 params[k] = v 25 } 26 27 body, ok := getBody(r) 28 if !ok { 29 return buildJsonRequestParser(params, resolver) 30 } 31 32 if len(params) == 0 { 33 return grpcurl.NewJSONRequestParser(body, resolver), nil 34 } 35 36 m := make(map[string]interface{}) 37 if err := json.NewDecoder(body).Decode(&m); err != nil { 38 return nil, err 39 } 40 41 for k, v := range params { 42 m[k] = v 43 } 44 45 return buildJsonRequestParser(m, resolver) 46 } 47 48 func buildJsonRequestParser(m map[string]interface{}, resolver jsonpb.AnyResolver) ( 49 grpcurl.RequestParser, error) { 50 var buf bytes.Buffer 51 if err := json.NewEncoder(&buf).Encode(m); err != nil { 52 return nil, err 53 } 54 55 return grpcurl.NewJSONRequestParser(&buf, resolver), nil 56 } 57 58 func getBody(r *http.Request) (io.Reader, bool) { 59 if r.Body == nil { 60 return nil, false 61 } 62 63 if r.ContentLength == 0 { 64 return nil, false 65 } 66 67 if r.ContentLength > 0 { 68 return r.Body, true 69 } 70 71 var buf bytes.Buffer 72 if _, err := io.Copy(&buf, r.Body); err != nil { 73 return nil, false 74 } 75 76 if buf.Len() > 0 { 77 return &buf, true 78 } 79 80 return nil, false 81 }