github.com/lingyao2333/mo-zero@v1.4.1/rest/httpx/requests.go (about) 1 package httpx 2 3 import ( 4 "io" 5 "net/http" 6 "strings" 7 8 "github.com/lingyao2333/mo-zero/core/mapping" 9 "github.com/lingyao2333/mo-zero/rest/internal/encoding" 10 "github.com/lingyao2333/mo-zero/rest/internal/header" 11 "github.com/lingyao2333/mo-zero/rest/pathvar" 12 ) 13 14 const ( 15 formKey = "form" 16 pathKey = "path" 17 maxMemory = 32 << 20 // 32MB 18 maxBodyLen = 8 << 20 // 8MB 19 separator = ";" 20 tokensInAttribute = 2 21 ) 22 23 var ( 24 formUnmarshaler = mapping.NewUnmarshaler(formKey, mapping.WithStringValues()) 25 pathUnmarshaler = mapping.NewUnmarshaler(pathKey, mapping.WithStringValues()) 26 ) 27 28 // Parse parses the request. 29 func Parse(r *http.Request, v interface{}) error { 30 if err := ParsePath(r, v); err != nil { 31 return err 32 } 33 34 if err := ParseForm(r, v); err != nil { 35 return err 36 } 37 38 if err := ParseHeaders(r, v); err != nil { 39 return err 40 } 41 42 return ParseJsonBody(r, v) 43 } 44 45 // ParseHeaders parses the headers request. 46 func ParseHeaders(r *http.Request, v interface{}) error { 47 return encoding.ParseHeaders(r.Header, v) 48 } 49 50 // ParseForm parses the form request. 51 func ParseForm(r *http.Request, v interface{}) error { 52 params, err := GetFormValues(r) 53 if err != nil { 54 return err 55 } 56 57 return formUnmarshaler.Unmarshal(params, v) 58 } 59 60 // ParseHeader parses the request header and returns a map. 61 func ParseHeader(headerValue string) map[string]string { 62 ret := make(map[string]string) 63 fields := strings.Split(headerValue, separator) 64 65 for _, field := range fields { 66 field = strings.TrimSpace(field) 67 if len(field) == 0 { 68 continue 69 } 70 71 kv := strings.SplitN(field, "=", tokensInAttribute) 72 if len(kv) != tokensInAttribute { 73 continue 74 } 75 76 ret[kv[0]] = kv[1] 77 } 78 79 return ret 80 } 81 82 // ParseJsonBody parses the post request which contains json in body. 83 func ParseJsonBody(r *http.Request, v interface{}) error { 84 if withJsonBody(r) { 85 reader := io.LimitReader(r.Body, maxBodyLen) 86 return mapping.UnmarshalJsonReader(reader, v) 87 } 88 89 return mapping.UnmarshalJsonMap(nil, v) 90 } 91 92 // ParsePath parses the symbols reside in url path. 93 // Like http://localhost/bag/:name 94 func ParsePath(r *http.Request, v interface{}) error { 95 vars := pathvar.Vars(r) 96 m := make(map[string]interface{}, len(vars)) 97 for k, v := range vars { 98 m[k] = v 99 } 100 101 return pathUnmarshaler.Unmarshal(m, v) 102 } 103 104 func withJsonBody(r *http.Request) bool { 105 return r.ContentLength > 0 && strings.Contains(r.Header.Get(header.ContentType), header.ApplicationJson) 106 }