mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-14 15:56:44 +03:00
Call Close on user values stored via RequestCtx.SetUserValue if these values implement io.Closer
This commit is contained in:
@@ -359,7 +359,9 @@ func (ctx *RequestCtx) Hijack(handler HijackHandler) {
|
||||
// This functionality may be useful for passing arbitrary values between
|
||||
// functions involved in request processing.
|
||||
//
|
||||
// All the values stored in ctx are deleted after returning from RequestHandler.
|
||||
// All the values are removed from ctx after returning from the top
|
||||
// RequestHandler. Additionally, Close method is called on each value
|
||||
// implementing io.Closer before removing the value from ctx.
|
||||
func (ctx *RequestCtx) SetUserValue(key string, value interface{}) {
|
||||
ctx.userValues.Set(key, value)
|
||||
}
|
||||
|
||||
+12
@@ -1,5 +1,9 @@
|
||||
package fasthttp
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type userDataKV struct {
|
||||
key []byte
|
||||
value interface{}
|
||||
@@ -55,5 +59,13 @@ func (d *userData) GetBytes(key []byte) interface{} {
|
||||
}
|
||||
|
||||
func (d *userData) Reset() {
|
||||
args := *d
|
||||
n := len(args)
|
||||
for i := 0; i < n; i++ {
|
||||
v := args[i].value
|
||||
if vc, ok := v.(io.Closer); ok {
|
||||
vc.Close()
|
||||
}
|
||||
}
|
||||
*d = (*d)[:0]
|
||||
}
|
||||
|
||||
@@ -39,3 +39,36 @@ func testUserDataGet(t *testing.T, u *userData, key []byte, value interface{}) {
|
||||
t.Fatalf("unexpected value for key=%q: %d. Expecting %d", key, v, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserDataValueClose(t *testing.T) {
|
||||
var u userData
|
||||
|
||||
closeCalls := 0
|
||||
|
||||
// store values implementing io.Closer
|
||||
for i := 0; i < 5; i++ {
|
||||
key := fmt.Sprintf("key_%d", i)
|
||||
u.Set(key, &closerValue{&closeCalls})
|
||||
}
|
||||
|
||||
// store values without io.Closer
|
||||
for i := 0; i < 10; i++ {
|
||||
key := fmt.Sprintf("key_noclose_%d", i)
|
||||
u.Set(key, i)
|
||||
}
|
||||
|
||||
u.Reset()
|
||||
|
||||
if closeCalls != 5 {
|
||||
t.Fatalf("unexpected number of Close calls: %d. Expecting 10", closeCalls)
|
||||
}
|
||||
}
|
||||
|
||||
type closerValue struct {
|
||||
closeCalls *int
|
||||
}
|
||||
|
||||
func (cv *closerValue) Close() error {
|
||||
(*cv.closeCalls)++
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user