2019-07-18 22:36:05 +03:00
package metrics
import (
"bufio"
"net"
"net/http"
)
2019-12-10 20:18:04 +03:00
type recorder interface {
http . ResponseWriter
http . Flusher
getCode ( ) int
}
func newResponseRecorder ( rw http . ResponseWriter ) recorder {
rec := & responseRecorder {
ResponseWriter : rw ,
statusCode : http . StatusOK ,
}
if _ , ok := rw . ( http . CloseNotifier ) ; ! ok {
return rec
}
2019-12-12 17:12:05 +03:00
return & responseRecorderWithCloseNotify { rec }
2019-12-10 20:18:04 +03:00
}
2019-07-18 22:36:05 +03:00
// responseRecorder captures information from the response and preserves it for
// later analysis.
type responseRecorder struct {
http . ResponseWriter
statusCode int
}
2019-12-10 20:18:04 +03:00
type responseRecorderWithCloseNotify struct {
* responseRecorder
}
// CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone away.
func ( r * responseRecorderWithCloseNotify ) CloseNotify ( ) <- chan bool {
return r . ResponseWriter . ( http . CloseNotifier ) . CloseNotify ( )
}
func ( r * responseRecorder ) getCode ( ) int {
return r . statusCode
}
2019-07-18 22:36:05 +03:00
// WriteHeader captures the status code for later retrieval.
func ( r * responseRecorder ) WriteHeader ( status int ) {
r . ResponseWriter . WriteHeader ( status )
r . statusCode = status
}
// Hijack hijacks the connection
func ( r * responseRecorder ) Hijack ( ) ( net . Conn , * bufio . ReadWriter , error ) {
return r . ResponseWriter . ( http . Hijacker ) . Hijack ( )
}
// Flush sends any buffered data to the client.
func ( r * responseRecorder ) Flush ( ) {
2019-09-30 15:42:04 +03:00
if f , ok := r . ResponseWriter . ( http . Flusher ) ; ok {
f . Flush ( )
}
2019-07-18 22:36:05 +03:00
}