Repository: cloudwego/hertz
Pull request #440 (2022-12-01 04:04:59)

feat: add `resp.SetBodyStreamNoReset` method
#### What type of PR is this?
<!--
Add one of the following kinds:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->
feat
#### Check the PR title.
<!--
The description of the title will be attached in Release Notes, 
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [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) Translate the PR title into Chinese.
添加 `resp.SetBodyStreamNoReset` 方法

#### (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: In the client streaming scenario gateway, the user wants to get the original bodystream for streaming processing, and put the processed data into a new resp bodystream and return it to the server. But the current SetBodyStream will turn off the original bodystream and the data cannot be processed, so add the SetBodyStreamNoReset method
zh(optional): 在 client 流式场景网关中，用户想要将原来的 bodystream 拿到进行流式处理，并将流式处理处理后的数据放到一个新的 resp bodystream 返回给 server。但是现在的 SetBodyStream 会将原来的 bodystream 关掉导致无法处理数据，所以添加 SetBodyStreamNoReset 方法

#### Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->


codecov[bot]: # [Codecov](https://codecov.io/gh/cloudwego/hertz/pull/440?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) Report
Base: **68.05**% // Head: **68.16**% // Increases project coverage by **`+0.11%`** :tada:
> Coverage data is based on head [(`3a4500f`)](https://codecov.io/gh/cloudwego/hertz/pull/440?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) compared to base [(`f4b9e2b`)](https://codecov.io/gh/cloudwego/hertz/commit/f4b9e2b17dd345c086c0bf0af6c744df5fb6f8f5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).
> Patch coverage: 100.00% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop     #440      +/-   ##
===========================================
+ Coverage    68.05%   68.16%   +0.11%     
===========================================
  Files           90       90              
  Lines         8627     8630       +3     
===========================================
+ Hits          5871     5883      +12     
+ Misses        2395     2387       -8     
+ Partials       361      360       -1     
```


| [Impacted Files](https://codecov.io/gh/cloudwego/hertz/pull/440?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) | Coverage Δ | |
|---|---|---|
| [pkg/protocol/response.go](https://codecov.io/gh/cloudwego/hertz/pull/440/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego#diff-cGtnL3Byb3RvY29sL3Jlc3BvbnNlLmdv) | `82.78% <100.00%> (+1.70%)` | :arrow_up: |
| [pkg/common/compress/compress.go](https://codecov.io/gh/cloudwego/hertz/pull/440/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego#diff-cGtnL2NvbW1vbi9jb21wcmVzcy9jb21wcmVzcy5nbw==) | `83.80% <0.00%> (+2.85%)` | :arrow_up: |
| [pkg/common/timer/timer.go](https://codecov.io/gh/cloudwego/hertz/pull/440/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego#diff-cGtnL2NvbW1vbi90aW1lci90aW1lci5nbw==) | `80.95% <0.00%> (+19.04%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/cloudwego/hertz/pull/440?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).


Patch:
diff --git a/pkg/protocol/response.go b/pkg/protocol/response.go
index a170ffd..f46395b 100644
--- a/pkg/protocol/response.go
+++ b/pkg/protocol/response.go
@@ -193,6 +193,13 @@ func (resp *Response) SetBodyStream(bodyStream io.Reader, bodySize int) {
 	resp.Header.SetContentLength(bodySize)
 }
 
+// SetBodyStreamNoReset is almost the same as SetBodyStream,
+// but it doesn't reset the bodyStream before.
+func (resp *Response) SetBodyStreamNoReset(bodyStream io.Reader, bodySize int) {
+	resp.bodyStream = bodyStream
+	resp.Header.SetContentLength(bodySize)
+}
+
 // BodyE returns response body.
 func (resp *Response) BodyE() ([]byte, error) {
 	if resp.bodyStream != nil {


Test patch:
diff --git a/pkg/protocol/response_test.go b/pkg/protocol/response_test.go
index 7195eec..4f2f56e 100644
--- a/pkg/protocol/response_test.go
+++ b/pkg/protocol/response_test.go
@@ -229,3 +229,30 @@ func TestResponseAcquireResponse(t *testing.T) {
 	ReleaseResponse(resp1)
 	assert.Nil(t, resp1.body)
 }
+
+type closeBuffer struct {
+	*bytes.Buffer
+}
+
+func (b *closeBuffer) Close() error {
+	b.Reset()
+	return nil
+}
+
+func TestSetBodyStreamNoReset(t *testing.T) {
+	t.Parallel()
+	resp := Response{}
+	bsA := &closeBuffer{bytes.NewBufferString("A")}
+	bsB := &closeBuffer{bytes.NewBufferString("B")}
+	bsC := &closeBuffer{bytes.NewBufferString("C")}
+
+	resp.SetBodyStream(bsA, 1)
+	resp.SetBodyStreamNoReset(bsB, 1)
+	// resp.Body() has closed bsB
+	assert.DeepEqual(t, string(resp.Body()), "B")
+	assert.DeepEqual(t, bsA.String(), "A")
+
+	resp.bodyStream = bsA
+	resp.SetBodyStream(bsC, 1)
+	assert.DeepEqual(t, bsA.String(), "")
+}