File tree Expand file tree Collapse file tree 3 files changed +58
-10
lines changed
Expand file tree Collapse file tree 3 files changed +58
-10
lines changed Original file line number Diff line number Diff line change @@ -178,6 +178,22 @@ func (r *Request) IsAjaxRequest() bool {
178178 return strings .EqualFold (r .Header .Get ("X-Requested-With" ), "XMLHttpRequest" )
179179}
180180
181+ // IsMultiPartRequest checks and returns whether current request is an MultiPart request.
182+ func (r * Request ) IsMultiPartRequest () bool {
183+ if contentType := r .Header .Get ("Content-Type" ); contentType != "" {
184+ return gstr .Contains (contentType , "multipart/" )
185+ }
186+ return false
187+ }
188+
189+ // IsFormRequest checks and returns whether current request is an Form request.
190+ func (r * Request ) IsFormRequest () bool {
191+ if contentType := r .Header .Get ("Content-Type" ); contentType != "" {
192+ return gstr .Contains (contentType , "form" )
193+ }
194+ return false
195+ }
196+
181197// GetClientIp returns the client ip of this request without port.
182198// Note that this ip address might be modified by client header.
183199func (r * Request ) GetClientIp () string {
Original file line number Diff line number Diff line change @@ -269,27 +269,23 @@ func (r *Request) parseForm() {
269269 return
270270 }
271271 if contentType := r .Header .Get ("Content-Type" ); contentType != "" {
272- var (
273- err error
274- repeatableRead = true
275- )
276- if gstr .Contains (contentType , "multipart/" ) {
272+ var err error
273+ if ! r .IsMultiPartRequest () {
277274 // To avoid big memory consuming.
278275 // The `multipart/` type form always contains binary data, which is not necessary read twice.
279- repeatableRead = false
276+ r .MakeBodyRepeatableRead (true )
277+ }
278+ if r .IsMultiPartRequest () {
280279 // multipart/form-data, multipart/mixed
281280 if err = r .ParseMultipartForm (r .Server .config .FormParsingMemory ); err != nil {
282281 panic (gerror .WrapCode (gcode .CodeInvalidRequest , err , "r.ParseMultipartForm failed" ))
283282 }
284- } else if gstr . Contains ( contentType , "form" ) {
283+ } else if r . IsFormRequest ( ) {
285284 // application/x-www-form-urlencoded
286285 if err = r .Request .ParseForm (); err != nil {
287286 panic (gerror .WrapCode (gcode .CodeInvalidRequest , err , "r.Request.ParseForm failed" ))
288287 }
289288 }
290- if repeatableRead {
291- r .MakeBodyRepeatableRead (true )
292- }
293289 if len (r .PostForm ) > 0 {
294290 // Parse the form data using united parsing way.
295291 params := ""
Original file line number Diff line number Diff line change @@ -115,6 +115,42 @@ func Test_Params_ParseForm(t *testing.T) {
115115 })
116116}
117117
118+ // https://github.com/gogf/gf/pull/4143
119+ func Test_Params_ParseForm_FixMakeBodyRepeatableRead (t * testing.T ) {
120+ type User struct {
121+ Id int
122+ Name string
123+ }
124+ s := g .Server (guid .S ())
125+ s .BindHandler ("/parse-form" , func (r * ghttp.Request ) {
126+ var user * User
127+ if err := r .ParseForm (& user ); err != nil {
128+ r .Response .WriteExit (err )
129+ }
130+ hasBody := len (r .GetBody ()) > 0
131+ r .Response .WriteExit (hasBody )
132+ })
133+ s .SetDumpRouterMap (false )
134+ s .Start ()
135+ defer s .Shutdown ()
136+
137+ time .Sleep (100 * time .Millisecond )
138+ gtest .C (t , func (t * gtest.T ) {
139+ c := g .Client ()
140+ c .SetPrefix (fmt .Sprintf ("http://127.0.0.1:%d" , s .GetListenedPort ()))
141+ t .Assert (c .GetContent (ctx , "/parse-form" ), `false` )
142+ t .Assert (c .GetContent (ctx , "/parse-form" , g.Map {
143+ "id" : 1 ,
144+ "name" : "john" ,
145+ }), false )
146+ t .Assert (c .PostContent (ctx , "/parse-form" ), `false` )
147+ t .Assert (c .PostContent (ctx , "/parse-form" , g.Map {
148+ "id" : 1 ,
149+ "name" : "john" ,
150+ }), true )
151+ })
152+ }
153+
118154func Test_Params_ComplexJsonStruct (t * testing.T ) {
119155 type ItemEnv struct {
120156 Type string
You can’t perform that action at this time.
0 commit comments