Skip to content

Commit 7f199fe

Browse files
committed
fix(net/ghttp) parseForm MakeBodyRepeatableRead not effective
1 parent 20b1987 commit 7f199fe

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

net/ghttp/ghttp_request.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff 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.
183199
func (r *Request) GetClientIp() string {

net/ghttp/ghttp_request_param.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff 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 := ""

net/ghttp/ghttp_z_unit_feature_request_struct_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
118154
func Test_Params_ComplexJsonStruct(t *testing.T) {
119155
type ItemEnv struct {
120156
Type string

0 commit comments

Comments
 (0)