Repository: cloudwego/hertz (go)

Issue:
fix: ignore body should not set content-length 
**Describe the bug**

refer to fasthttp https://github.com/valyala/fasthttp/pull/1019 and https://github.com/valyala/fasthttp/pull/1022


Pull request:
fix: ignore body should not set content-length 
#### What type of PR is this?
fix

#### Check the PR title.
- [x] This PR title match the format: \<type\>(optional scope): \<description\>
- [x] The description of this PR title is user-oriented and clear enough for others to understand.




#### (Optional) More detail description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review. If it is a perf type PR, perf data is suggested to give.
-->
en: can refer to https://github.com/valyala/fasthttp/pull/1022, fasthttp only handle ContinueReadBody(), this pr also handle ContinueReadBodyStream() 
zh(optional):  fasthttp 只处理了 ContinueReadBody(), 这里添加了对 ContinueReadBodyStream() 的处理 和 测试

#### Which issue(s) this PR fixes:
close #320 


Patch:
diff --git a/pkg/protocol/http1/req/request.go b/pkg/protocol/http1/req/request.go
index eea2dae..895aeaa 100644
--- a/pkg/protocol/http1/req/request.go
+++ b/pkg/protocol/http1/req/request.go
@@ -275,7 +275,11 @@ func ContinueReadBodyStream(req *protocol.Request, zr network.Reader, maxBodySiz
 		// the end of body is determined by connection close.
 		// So just ignore request body for requests without
 		// 'Content-Length' and 'Transfer-Encoding' headers.
-		req.Header.SetContentLength(0)
+
+		// refer to https://tools.ietf.org/html/rfc7230#section-3.3.2
+		if !req.Header.IgnoreBody() {
+			req.Header.SetContentLength(0)
+		}
 		return nil
 	}
 
@@ -339,7 +343,11 @@ func ContinueReadBody(req *protocol.Request, r network.Reader, maxBodySize int,
 		// the end of body is determined by connection close.
 		// So just ignore request body for requests without
 		// 'Content-Length' and 'Transfer-Encoding' headers.
-		req.Header.SetContentLength(0)
+
+		// refer to https://tools.ietf.org/html/rfc7230#section-3.3.2
+		if !req.Header.IgnoreBody() {
+			req.Header.SetContentLength(0)
+		}
 		return nil
 	}
 


Test patch:
diff --git a/pkg/protocol/http1/req/request_test.go b/pkg/protocol/http1/req/request_test.go
index fc2fe71..8991ab0 100644
--- a/pkg/protocol/http1/req/request_test.go
+++ b/pkg/protocol/http1/req/request_test.go
@@ -92,6 +92,90 @@ func TestRequestContinueReadBody(t *testing.T) {
 	}
 }
 
+func TestRequestReadNoBody(t *testing.T) {
+	t.Parallel()
+
+	var r protocol.Request
+
+	s := "GET / HTTP/1.1\r\n\r\n"
+
+	zr := mock.NewZeroCopyReader(s)
+	if err := Read(&r, zr); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	r.SetHost("foobar")
+	headerStr := r.Header.String()
+	if strings.Contains(headerStr, "Content-Length: ") {
+		t.Fatalf("unexpected Content-Length")
+	}
+}
+
+func TestRequestRead(t *testing.T) {
+	t.Parallel()
+
+	var r protocol.Request
+
+	s := "POST / HTTP/1.1\r\n\r\n"
+
+	zr := mock.NewZeroCopyReader(s)
+	if err := Read(&r, zr); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	r.SetHost("foobar")
+	headerStr := r.Header.String()
+	if !strings.Contains(headerStr, "Content-Length: ") {
+		t.Fatalf("should contain Content-Length")
+	}
+	cLen := r.Header.Peek(consts.HeaderContentLength)
+	if string(cLen) != "0" {
+		t.Fatalf("unexpected Content-Length: %s, Expecting 0", string(cLen))
+	}
+}
+
+func TestRequestReadNoBodyStreaming(t *testing.T) {
+	t.Parallel()
+
+	var r protocol.Request
+	r.Header.SetContentLength(-2)
+	r.Header.SetMethod("GET")
+
+	s := ""
+
+	zr := mock.NewZeroCopyReader(s)
+	if err := ContinueReadBodyStream(&r, zr, 2048, true); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	r.SetHost("foobar")
+	headerStr := r.Header.String()
+	if strings.Contains(headerStr, "Content-Length: ") {
+		t.Fatalf("unexpected Content-Length")
+	}
+}
+
+func TestRequestReadStreaming(t *testing.T) {
+	t.Parallel()
+
+	var r protocol.Request
+	r.Header.SetContentLength(-2)
+	r.Header.SetMethod("POST")
+
+	s := ""
+
+	zr := mock.NewZeroCopyReader(s)
+	if err := ContinueReadBodyStream(&r, zr, 2048, true); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	r.SetHost("foobar")
+	headerStr := r.Header.String()
+	if !strings.Contains(headerStr, "Content-Length: ") {
+		t.Fatalf("should contain Content-Length")
+	}
+	cLen := r.Header.Peek(consts.HeaderContentLength)
+	if string(cLen) != "0" {
+		t.Fatalf("unexpected Content-Length: %s, Expecting 0", string(cLen))
+	}
+}
+
 func TestMethodAndPathAndQueryString(t *testing.T) {
 	s := "PUT /foo/bar?query=1 HTTP/1.1\r\nExpect: 100-continue\r\nContent-Length: 5\r\nContent-Type: foo/bar\r\n\r\nabcdef4343"
 	zr := mock.NewZeroCopyReader(s)