CloseNotifier: return pointer instead of value
This commit is contained in:
parent
e2982185d6
commit
61e59d74e0
4 changed files with 95 additions and 17 deletions
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ middlewares.Stateful = &captureResponseWriter{}
|
||||
_ middlewares.Stateful = &captureResponseWriterWithCloseNotify{}
|
||||
)
|
||||
|
||||
type capturer interface {
|
||||
|
@ -24,7 +24,7 @@ func newCaptureResponseWriter(rw http.ResponseWriter) capturer {
|
|||
if _, ok := rw.(http.CloseNotifier); !ok {
|
||||
return capt
|
||||
}
|
||||
return captureResponseWriterWithCloseNotify{capt}
|
||||
return &captureResponseWriterWithCloseNotify{capt}
|
||||
}
|
||||
|
||||
// captureResponseWriter is a wrapper of type http.ResponseWriter
|
||||
|
@ -76,13 +76,6 @@ func (crw *captureResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
|
|||
return nil, nil, fmt.Errorf("not a hijacker: %T", crw.rw)
|
||||
}
|
||||
|
||||
func (crw *captureResponseWriter) CloseNotify() <-chan bool {
|
||||
if c, ok := crw.rw.(http.CloseNotifier); ok {
|
||||
return c.CloseNotify()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (crw *captureResponseWriter) Status() int {
|
||||
return crw.status
|
||||
}
|
||||
|
|
50
pkg/middlewares/accesslog/capture_response_writer_test.go
Normal file
50
pkg/middlewares/accesslog/capture_response_writer_test.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package accesslog
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type rwWithCloseNotify struct {
|
||||
*httptest.ResponseRecorder
|
||||
}
|
||||
|
||||
func (r *rwWithCloseNotify) CloseNotify() <-chan bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func TestCloseNotifier(t *testing.T) {
|
||||
testCases := []struct {
|
||||
rw http.ResponseWriter
|
||||
desc string
|
||||
implementsCloseNotifier bool
|
||||
}{
|
||||
{
|
||||
rw: httptest.NewRecorder(),
|
||||
desc: "does not implement CloseNotifier",
|
||||
implementsCloseNotifier: false,
|
||||
},
|
||||
{
|
||||
rw: &rwWithCloseNotify{httptest.NewRecorder()},
|
||||
desc: "implements CloseNotifier",
|
||||
implementsCloseNotifier: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, ok := test.rw.(http.CloseNotifier)
|
||||
assert.Equal(t, test.implementsCloseNotifier, ok)
|
||||
|
||||
rw := newCaptureResponseWriter(test.rw)
|
||||
_, impl := rw.(http.CloseNotifier)
|
||||
assert.Equal(t, test.implementsCloseNotifier, impl)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// CollectingCounter is a metrics.Counter implementation that enables access to the CounterValue and LastLabelValues.
|
||||
|
@ -56,3 +57,44 @@ func newCollectingRetryMetrics() *collectingRetryMetrics {
|
|||
func (m *collectingRetryMetrics) ServiceRetriesCounter() metrics.Counter {
|
||||
return m.retriesCounter
|
||||
}
|
||||
|
||||
type rwWithCloseNotify struct {
|
||||
*httptest.ResponseRecorder
|
||||
}
|
||||
|
||||
func (r *rwWithCloseNotify) CloseNotify() <-chan bool {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func TestCloseNotifier(t *testing.T) {
|
||||
testCases := []struct {
|
||||
rw http.ResponseWriter
|
||||
desc string
|
||||
implementsCloseNotifier bool
|
||||
}{
|
||||
{
|
||||
rw: httptest.NewRecorder(),
|
||||
desc: "does not implement CloseNotifier",
|
||||
implementsCloseNotifier: false,
|
||||
},
|
||||
{
|
||||
rw: &rwWithCloseNotify{httptest.NewRecorder()},
|
||||
desc: "implements CloseNotifier",
|
||||
implementsCloseNotifier: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, ok := test.rw.(http.CloseNotifier)
|
||||
assert.Equal(t, test.implementsCloseNotifier, ok)
|
||||
|
||||
rw := newResponseRecorder(test.rw)
|
||||
_, impl := rw.(http.CloseNotifier)
|
||||
assert.Equal(t, test.implementsCloseNotifier, impl)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ func newResponseRecorder(rw http.ResponseWriter) recorder {
|
|||
if _, ok := rw.(http.CloseNotifier); !ok {
|
||||
return rec
|
||||
}
|
||||
return responseRecorderWithCloseNotify{rec}
|
||||
return &responseRecorderWithCloseNotify{rec}
|
||||
}
|
||||
|
||||
// responseRecorder captures information from the response and preserves it for
|
||||
|
@ -55,13 +55,6 @@ func (r *responseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|||
return r.ResponseWriter.(http.Hijacker).Hijack()
|
||||
}
|
||||
|
||||
// CloseNotify returns a channel that receives at most a
|
||||
// single value (true) when the client connection has gone
|
||||
// away.
|
||||
func (r *responseRecorder) CloseNotify() <-chan bool {
|
||||
return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||
}
|
||||
|
||||
// Flush sends any buffered data to the client.
|
||||
func (r *responseRecorder) Flush() {
|
||||
if f, ok := r.ResponseWriter.(http.Flusher); ok {
|
||||
|
|
Loading…
Reference in a new issue