Skip to content

Commit a1db411

Browse files
StreamRequestBody shouldn't read more data than actual need. (#1819)
* The StreamRequestBody should not read content beyond what is required. The StreamRequestBody feature on the server side should not read content that does not belong to the current request body.This is more logical and consistent with the result of not using the StreamRequestBody feature.Fixes: #1816. * Update server_test.go Co-authored-by: Erik Dubbelboer <[email protected]> * Update http.go Co-authored-by: Erik Dubbelboer <[email protected]> --------- Co-authored-by: Erik Dubbelboer <[email protected]>
1 parent 38a91cd commit a1db411

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

http.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,12 +2283,13 @@ func readBodyWithStreaming(r *bufio.Reader, contentLength, maxBodySize int, dst
22832283
readN = 8 * 1024
22842284
}
22852285

2286-
if contentLength >= 0 && maxBodySize >= contentLength {
2287-
b, err = appendBodyFixedSize(r, dst, readN)
2288-
} else {
2289-
b, err = readBodyIdentity(r, readN, dst)
2290-
}
2291-
2286+
// A fixed-length pre-read function should be used here; otherwise,
2287+
// it may read content beyond the request body into areas outside
2288+
// the br buffer. This could affect the handling of the next request
2289+
// in the br buffer, if there is one. The original two branches can
2290+
// be handled with this single branch. by the way,
2291+
// fix issue: https://github.com/valyala/fasthttp/issues/1816
2292+
b, err = appendBodyFixedSize(r, dst, readN)
22922293
if err != nil {
22932294
return b, err
22942295
}

server_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4358,3 +4358,50 @@ func (cl *testLogger) Printf(format string, args ...any) {
43584358
cl.out += fmt.Sprintf(format, args...)[6:] + "\n"
43594359
cl.lock.Unlock()
43604360
}
4361+
4362+
func TestRequestBodyStreamReadIssue1816(t *testing.T) {
4363+
pcs := fasthttputil.NewPipeConns()
4364+
cliCon, serverCon := pcs.Conn1(), pcs.Conn2()
4365+
go func() {
4366+
req := AcquireRequest()
4367+
defer ReleaseRequest(req)
4368+
req.Header.SetContentLength(10)
4369+
req.Header.SetMethod("POST")
4370+
req.SetRequestURI("http://localhsot:8080")
4371+
req.SetBodyRaw(bytes.Repeat([]byte{'1'}, 10))
4372+
var pipelineReqBody []byte
4373+
reqBody := req.String()
4374+
pipelineReqBody = append(pipelineReqBody, reqBody...)
4375+
pipelineReqBody = append(pipelineReqBody, reqBody...)
4376+
_, err := cliCon.Write(pipelineReqBody)
4377+
if err != nil {
4378+
t.Error(err)
4379+
}
4380+
resp := AcquireResponse()
4381+
err = resp.Read(bufio.NewReader(cliCon))
4382+
if err != nil {
4383+
t.Error(err)
4384+
}
4385+
err = cliCon.Close()
4386+
if err != nil {
4387+
t.Error(err)
4388+
}
4389+
}()
4390+
server := Server{StreamRequestBody: true, MaxRequestBodySize: 5, Handler: func(ctx *RequestCtx) {
4391+
r := ctx.RequestBodyStream()
4392+
p := make([]byte, 1300)
4393+
for {
4394+
_, err := r.Read(p)
4395+
if err != nil {
4396+
if err != io.EOF {
4397+
t.Fatal(err)
4398+
}
4399+
break
4400+
}
4401+
}
4402+
}}
4403+
err := server.serveConn(serverCon)
4404+
if err != nil {
4405+
t.Fatal(err)
4406+
}
4407+
}

0 commit comments

Comments
 (0)