| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 | 
							- package echo
 
- import (
 
- 	"bufio"
 
- 	"net"
 
- 	"net/http"
 
- )
 
- type (
 
- 	// Response wraps an http.ResponseWriter and implements its interface to be used
 
- 	// by an HTTP handler to construct an HTTP response.
 
- 	// See: https://golang.org/pkg/net/http/#ResponseWriter
 
- 	Response struct {
 
- 		echo        *Echo
 
- 		beforeFuncs []func()
 
- 		afterFuncs  []func()
 
- 		Writer      http.ResponseWriter
 
- 		Status      int
 
- 		Size        int64
 
- 		Committed   bool
 
- 	}
 
- )
 
- // NewResponse creates a new instance of Response.
 
- func NewResponse(w http.ResponseWriter, e *Echo) (r *Response) {
 
- 	return &Response{Writer: w, echo: e}
 
- }
 
- // Header returns the header map for the writer that will be sent by
 
- // WriteHeader. Changing the header after a call to WriteHeader (or Write) has
 
- // no effect unless the modified headers were declared as trailers by setting
 
- // the "Trailer" header before the call to WriteHeader (see example)
 
- // To suppress implicit response headers, set their value to nil.
 
- // Example: https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
 
- func (r *Response) Header() http.Header {
 
- 	return r.Writer.Header()
 
- }
 
- // Before registers a function which is called just before the response is written.
 
- func (r *Response) Before(fn func()) {
 
- 	r.beforeFuncs = append(r.beforeFuncs, fn)
 
- }
 
- // After registers a function which is called just after the response is written.
 
- // If the `Content-Length` is unknown, none of the after function is executed.
 
- func (r *Response) After(fn func()) {
 
- 	r.afterFuncs = append(r.afterFuncs, fn)
 
- }
 
- // WriteHeader sends an HTTP response header with status code. If WriteHeader is
 
- // not called explicitly, the first call to Write will trigger an implicit
 
- // WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly
 
- // used to send error codes.
 
- func (r *Response) WriteHeader(code int) {
 
- 	if r.Committed {
 
- 		r.echo.Logger.Warn("response already committed")
 
- 		return
 
- 	}
 
- 	for _, fn := range r.beforeFuncs {
 
- 		fn()
 
- 	}
 
- 	r.Status = code
 
- 	r.Writer.WriteHeader(code)
 
- 	r.Committed = true
 
- }
 
- // Write writes the data to the connection as part of an HTTP reply.
 
- func (r *Response) Write(b []byte) (n int, err error) {
 
- 	if !r.Committed {
 
- 		r.WriteHeader(http.StatusOK)
 
- 	}
 
- 	n, err = r.Writer.Write(b)
 
- 	r.Size += int64(n)
 
- 	for _, fn := range r.afterFuncs {
 
- 		fn()
 
- 	}
 
- 	return
 
- }
 
- // Flush implements the http.Flusher interface to allow an HTTP handler to flush
 
- // buffered data to the client.
 
- // See [http.Flusher](https://golang.org/pkg/net/http/#Flusher)
 
- func (r *Response) Flush() {
 
- 	r.Writer.(http.Flusher).Flush()
 
- }
 
- // Hijack implements the http.Hijacker interface to allow an HTTP handler to
 
- // take over the connection.
 
- // See [http.Hijacker](https://golang.org/pkg/net/http/#Hijacker)
 
- func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 
- 	return r.Writer.(http.Hijacker).Hijack()
 
- }
 
- // CloseNotify implements the http.CloseNotifier interface to allow detecting
 
- // when the underlying connection has gone away.
 
- // This mechanism can be used to cancel long operations on the server if the
 
- // client has disconnected before the response is ready.
 
- // See [http.CloseNotifier](https://golang.org/pkg/net/http/#CloseNotifier)
 
- func (r *Response) CloseNotify() <-chan bool {
 
- 	return r.Writer.(http.CloseNotifier).CloseNotify()
 
- }
 
- func (r *Response) reset(w http.ResponseWriter) {
 
- 	r.beforeFuncs = nil
 
- 	r.afterFuncs = nil
 
- 	r.Writer = w
 
- 	r.Size = 0
 
- 	r.Status = http.StatusOK
 
- 	r.Committed = false
 
- }
 
 
  |