You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
package main
import (
"fmt""net/http""net/http/httptest""testing""time""github.com/go-chi/chi/v5/middleware"
)
funcTestResponseController(t*testing.T) {
handler:=http.HandlerFunc(func(w http.ResponseWriter, r*http.Request) {
// use http.ResponseController to customize read deadlinerc:=http.NewResponseController(w)
iferr:=rc.SetReadDeadline(time.Now().Add(time.Minute)); err!=nil {
fmt.Printf("failed to set read deadline: %+v", err)
w.WriteHeader(500)
return
}
w.WriteHeader(200)
})
t.Run("works", func(t*testing.T) {
svr:=httptest.NewServer(
handler,
)
t.Cleanup(svr.Close)
resp, _:=http.Get(svr.URL)
// assert status codeifg, w:=resp.StatusCode, 200; g!=w {
t.Errorf("\ngot :%v\nwant:%v", g, w)
}
})
t.Run("works with the compress middleware", func(t*testing.T) {
// use compress middlewaresvr:=httptest.NewServer(
middleware.NewCompressor(6).Handler(handler),
)
t.Cleanup(svr.Close)
resp, _:=http.Get(svr.URL)
// assert status codeifg, w:=resp.StatusCode, 200; g!=w {
t.Errorf("\ngot :%v\nwant:%v", g, w)
}
})
}
Results:
=== RUN TestResponseController
=== RUN TestResponseController/works
=== RUN TestResponseController/works_with_the_compress_middleware
failed to set read deadline: feature not supported prog_test.go:46:
got :500
want:200
--- FAIL: TestResponseController (30.00s)
--- PASS: TestResponseController/works (30.00s)
--- FAIL: TestResponseController/works_with_the_compress_middleware (0.00s)
FAIL
This is because http.ResponseController requires ResponseWriter to implement the Unwrap method that returns the original ResponseWriter. See the following code in Go 1.20 source code:
// The ResponseWriter should be the original value passed to the Handler.ServeHTTP method,// or have an Unwrap method returning the original ResponseWriter.
// SetReadDeadline sets the deadline for reading the entire request, including the body.// Reads from the request body after the deadline has been exceeded will return an error.// A zero value means no deadline.//// Setting the read deadline after it has been exceeded will not extend it.func (c*ResponseController) SetReadDeadline(deadline time.Time) error {
rw:=c.rwfor {
switcht:=rw.(type) {
caseinterface{ SetReadDeadline(time.Time) error }:
returnt.SetReadDeadline(deadline)
caserwUnwrapper:
rw=t.Unwrap()
default:
returnerrNotSupported()
}
}
}
To solve this issue, we need to implement the Unwrap method in middleware.compressResponseWriter.
Note that middleware.basicWriter, which is returned by middleware.NewWrapResponseWriter, already implements the Unwrap method, so this issue does not occur with it.
The text was updated successfully, but these errors were encountered:
When using http.ResponseController introduced in Go 1.20 with middleware.Compress, an error occurs.
Example of reproduce: https://go.dev/play/p/z_auq0KiEBx
Results:
This is because http.ResponseController requires ResponseWriter to implement the Unwrap method that returns the original ResponseWriter. See the following code in Go 1.20 source code:
https://cs.opensource.google/go/go/+/refs/tags/go1.20.3:src/net/http/responsecontroller.go;l=23-24
https://cs.opensource.google/go/go/+/refs/tags/go1.20.3:src/net/http/responsecontroller.go;l=79-96
To solve this issue, we need to implement the Unwrap method in middleware.compressResponseWriter.
Note that middleware.basicWriter, which is returned by middleware.NewWrapResponseWriter, already implements the Unwrap method, so this issue does not occur with it.
The text was updated successfully, but these errors were encountered: