1
0
mirror of https://github.com/labstack/echo.git synced 2025-01-12 01:22:21 +02:00

Fixed #176, closed #831

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Vishal Rana 2017-06-28 17:01:48 -07:00
parent 17c4df3e77
commit f96c973a25
4 changed files with 48 additions and 15 deletions

View File

@ -1,4 +1,4 @@
<a href="https://echo.labstack.com"><img class="logo" height="40" src="https://cdn.labstack.com/images/echo-logo.svg"></a> <a href="https://echo.labstack.com"><img height="80" src="https://cdn.labstack.com/images/echo-logo.svg"></a>
[![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge) [![Sourcegraph](https://sourcegraph.com/github.com/labstack/echo/-/badge.svg?style=flat-square)](https://sourcegraph.com/github.com/labstack/echo?badge)
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/labstack/echo) [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/labstack/echo)

View File

@ -72,6 +72,7 @@ type (
TLSServer *http.Server TLSServer *http.Server
Listener net.Listener Listener net.Listener
TLSListener net.Listener TLSListener net.Listener
AutoTLSManager autocert.Manager
DisableHTTP2 bool DisableHTTP2 bool
Debug bool Debug bool
HideBanner bool HideBanner bool
@ -79,7 +80,6 @@ type (
Binder Binder Binder Binder
Validator Validator Validator Validator
Renderer Renderer Renderer Renderer
AutoTLSManager autocert.Manager
// Mutex sync.RWMutex // Mutex sync.RWMutex
Logger Logger Logger Logger
} }
@ -293,14 +293,16 @@ func New() (e *Echo) {
// NewContext returns a Context instance. // NewContext returns a Context instance.
func (e *Echo) NewContext(r *http.Request, w http.ResponseWriter) Context { func (e *Echo) NewContext(r *http.Request, w http.ResponseWriter) Context {
return &context{ c := &context{
request: r, request: r,
response: NewResponse(w, e), response: &Response{Writer: w},
store: make(Map), store: make(Map),
echo: e, echo: e,
pvalues: make([]string, *e.maxParam), pvalues: make([]string, *e.maxParam),
handler: NotFoundHandler, handler: NotFoundHandler,
} }
c.response.context = c
return c
} }
// Router returns router. // Router returns router.

View File

@ -11,18 +11,18 @@ type (
// by an HTTP handler to construct an HTTP response. // by an HTTP handler to construct an HTTP response.
// See: https://golang.org/pkg/net/http/#ResponseWriter // See: https://golang.org/pkg/net/http/#ResponseWriter
Response struct { Response struct {
context Context
beforeFuncs []BeforeResponseFunc
Writer http.ResponseWriter Writer http.ResponseWriter
Status int Status int
Size int64 Size int64
Committed bool Committed bool
echo *Echo
} }
)
// NewResponse creates a new instance of Response. // BeforeResponseFunc defines a function which is called just before writing the
func NewResponse(w http.ResponseWriter, e *Echo) (r *Response) { // response.
return &Response{Writer: w, echo: e} BeforeResponseFunc func(Context)
} )
// Header returns the header map for the writer that will be sent by // 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 // WriteHeader. Changing the header after a call to WriteHeader (or Write) has
@ -34,15 +34,23 @@ func (r *Response) Header() http.Header {
return r.Writer.Header() return r.Writer.Header()
} }
// Before registers a function which is called just before the response is written.
func (r *Response) Before(fn BeforeResponseFunc) {
r.beforeFuncs = append(r.beforeFuncs, fn)
}
// WriteHeader sends an HTTP response header with status code. If WriteHeader is // WriteHeader sends an HTTP response header with status code. If WriteHeader is
// not called explicitly, the first call to Write will trigger an implicit // not called explicitly, the first call to Write will trigger an implicit
// WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly // WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly
// used to send error codes. // used to send error codes.
func (r *Response) WriteHeader(code int) { func (r *Response) WriteHeader(code int) {
if r.Committed { if r.Committed {
r.echo.Logger.Warn("response already committed") r.context.Logger().Warn("response already committed")
return return
} }
// for _, fn := range r.beforeFuncs {
// fn(r.context)
// }
r.Status = code r.Status = code
r.Writer.WriteHeader(code) r.Writer.WriteHeader(code)
r.Committed = true r.Committed = true

23
response_test.go Normal file
View File

@ -0,0 +1,23 @@
package echo
import (
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestResponse(t *testing.T) {
e := New()
req := httptest.NewRequest(GET, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
res := &Response{context: c, Writer: rec}
// Before
res.Before(func(c Context) {
c.Response().Header().Set(HeaderServer, "echo")
})
res.Write([]byte("test"))
assert.Equal(t, "echo", rec.Header().Get(HeaderServer))
}