Skip to content

Commit 2441d6f

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

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

net/ghttp/ghttp_request_param.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,28 +268,28 @@ func (r *Request) parseForm() {
268268
if r.ContentLength == 0 {
269269
return
270270
}
271+
271272
if contentType := r.Header.Get("Content-Type"); contentType != "" {
272-
var (
273-
err error
274-
repeatableRead = true
275-
)
276-
if gstr.Contains(contentType, "multipart/") {
273+
var isMultiPartRequest = gstr.Contains(contentType, "multipart/")
274+
var isFormRequest = gstr.Contains(contentType, "form")
275+
var err error
276+
277+
if !isMultiPartRequest {
277278
// To avoid big memory consuming.
278279
// The `multipart/` type form always contains binary data, which is not necessary read twice.
279-
repeatableRead = false
280+
r.MakeBodyRepeatableRead(true)
281+
}
282+
if isMultiPartRequest {
280283
// multipart/form-data, multipart/mixed
281284
if err = r.ParseMultipartForm(r.Server.config.FormParsingMemory); err != nil {
282285
panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "r.ParseMultipartForm failed"))
283286
}
284-
} else if gstr.Contains(contentType, "form") {
287+
} else if isFormRequest {
285288
// application/x-www-form-urlencoded
286289
if err = r.Request.ParseForm(); err != nil {
287290
panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "r.Request.ParseForm failed"))
288291
}
289292
}
290-
if repeatableRead {
291-
r.MakeBodyRepeatableRead(true)
292-
}
293293
if len(r.PostForm) > 0 {
294294
// Parse the form data using united parsing way.
295295
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)