You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.0 KiB
85 lines
2.0 KiB
// Copyright 2015 The Tango Authors. All rights reserved. |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file. |
|
|
|
package tango |
|
|
|
import ( |
|
"bufio" |
|
"fmt" |
|
"net" |
|
"net/http" |
|
) |
|
|
|
// ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about |
|
// the response. It is recommended that middleware handlers use this construct to wrap a responsewriter |
|
// if the functionality calls for it. |
|
type ResponseWriter interface { |
|
http.ResponseWriter |
|
http.Flusher |
|
http.Hijacker |
|
// Status returns the status code of the response or 0 if the response has not been written. |
|
Status() int |
|
// Written returns whether or not the ResponseWriter has been written. |
|
Written() bool |
|
// Size returns the size of the response body. |
|
Size() int |
|
} |
|
|
|
type responseWriter struct { |
|
http.ResponseWriter |
|
status int |
|
size int |
|
} |
|
|
|
func (rw *responseWriter) reset(w http.ResponseWriter) { |
|
rw.ResponseWriter = w |
|
rw.status = 0 |
|
rw.size = 0 |
|
} |
|
|
|
func (rw *responseWriter) WriteHeader(s int) { |
|
rw.status = s |
|
rw.ResponseWriter.WriteHeader(s) |
|
} |
|
|
|
func (rw *responseWriter) Write(b []byte) (int, error) { |
|
if !rw.Written() { |
|
// The status will be StatusOK if WriteHeader has not been called yet |
|
rw.WriteHeader(http.StatusOK) |
|
} |
|
size, err := rw.ResponseWriter.Write(b) |
|
rw.size += size |
|
return size, err |
|
} |
|
|
|
func (rw *responseWriter) Status() int { |
|
return rw.status |
|
} |
|
|
|
func (rw *responseWriter) Size() int { |
|
return rw.size |
|
} |
|
|
|
func (rw *responseWriter) Written() bool { |
|
return rw.status != 0 |
|
} |
|
|
|
func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { |
|
hijacker, ok := rw.ResponseWriter.(http.Hijacker) |
|
if !ok { |
|
return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface") |
|
} |
|
return hijacker.Hijack() |
|
} |
|
|
|
func (rw *responseWriter) CloseNotify() <-chan bool { |
|
return rw.ResponseWriter.(http.CloseNotifier).CloseNotify() |
|
} |
|
|
|
func (rw *responseWriter) Flush() { |
|
flusher, ok := rw.ResponseWriter.(http.Flusher) |
|
if ok { |
|
flusher.Flush() |
|
} |
|
}
|
|
|