Skip to content

Commit

Permalink
Encapsulated fields and exposed public functions.
Browse files Browse the repository at this point in the history
Signed-off-by: Vishal Rana <[email protected]>
  • Loading branch information
vishr committed May 22, 2015
1 parent df924ff commit bf85c56
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 82 deletions.
59 changes: 37 additions & 22 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ type (
// Context represents context for the current request. It holds request and
// response objects, path parameters, data and registered handler.
Context struct {
Request *http.Request
Response *Response
Socket *websocket.Conn
request *http.Request
response *Response
socket *websocket.Conn
pnames []string
pvalues []string
store store
Expand All @@ -24,15 +24,30 @@ type (

func NewContext(req *http.Request, res *Response, e *Echo) *Context {
return &Context{
Request: req,
Response: res,
request: req,
response: res,
echo: e,
pnames: make([]string, e.maxParam),
pvalues: make([]string, e.maxParam),
store: make(store),
}
}

// Request returns *http.Request.
func (c *Context) Request() *http.Request {
return c.request
}

// Response returns *Response.
func (c *Context) Response() *Response {
return c.response
}

// Socket returns *websocket.Conn.
func (c *Context) Socket() *websocket.Conn {
return c.socket
}

// P returns path parameter by index.
func (c *Context) P(i uint8) (value string) {
l := uint8(len(c.pnames))
Expand All @@ -57,7 +72,7 @@ func (c *Context) Param(name string) (value string) {
// Bind binds the request body into specified type v. Default binder does it
// based on Content-Type header.
func (c *Context) Bind(i interface{}) error {
return c.echo.binder(c.Request, i)
return c.echo.binder(c.request, i)
}

// Render invokes the registered HTML template renderer and sends a text/html
Expand All @@ -66,37 +81,37 @@ func (c *Context) Render(code int, name string, data interface{}) error {
if c.echo.renderer == nil {
return RendererNotRegistered
}
c.Response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.Response.WriteHeader(code)
return c.echo.renderer.Render(c.Response, name, data)
c.response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.response.WriteHeader(code)
return c.echo.renderer.Render(c.response, name, data)
}

// JSON sends an application/json response with status code.
func (c *Context) JSON(code int, i interface{}) error {
c.Response.Header().Set(ContentType, ApplicationJSON+"; charset=utf-8")
c.Response.WriteHeader(code)
return json.NewEncoder(c.Response).Encode(i)
c.response.Header().Set(ContentType, ApplicationJSON+"; charset=utf-8")
c.response.WriteHeader(code)
return json.NewEncoder(c.response).Encode(i)
}

// String sends a text/plain response with status code.
func (c *Context) String(code int, s string) error {
c.Response.Header().Set(ContentType, TextPlain+"; charset=utf-8")
c.Response.WriteHeader(code)
_, err := c.Response.Write([]byte(s))
c.response.Header().Set(ContentType, TextPlain+"; charset=utf-8")
c.response.WriteHeader(code)
_, err := c.response.Write([]byte(s))
return err
}

// HTML sends a text/html response with status code.
func (c *Context) HTML(code int, html string) error {
c.Response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.Response.WriteHeader(code)
_, err := c.Response.Write([]byte(html))
c.response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.response.WriteHeader(code)
_, err := c.response.Write([]byte(html))
return err
}

// NoContent sends a response with no body and a status code.
func (c *Context) NoContent(code int) error {
c.Response.WriteHeader(code)
c.response.WriteHeader(code)
return nil
}

Expand All @@ -117,11 +132,11 @@ func (c *Context) Set(key string, val interface{}) {

// Redirect redirects the request using http.Redirect with status code.
func (c *Context) Redirect(code int, url string) {
http.Redirect(c.Response, c.Request, url, code)
http.Redirect(c.response, c.request, url, code)
}

func (c *Context) reset(w http.ResponseWriter, r *http.Request, e *Echo) {
c.Request = r
c.Response.reset(w)
c.request = r
c.response.reset(w)
c.echo = e
}
8 changes: 4 additions & 4 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,26 +91,26 @@ func TestContext(t *testing.T) {

// JSON
r.Header.Set(Accept, ApplicationJSON)
c.Response.committed = false
c.response.committed = false
if he := c.JSON(http.StatusOK, u1); he != nil {
t.Errorf("json %#v", he)
}

// String
r.Header.Set(Accept, TextPlain)
c.Response.committed = false
c.response.committed = false
if he := c.String(http.StatusOK, "Hello, World!"); he != nil {
t.Errorf("string %#v", he.Error)
}

// HTML
r.Header.Set(Accept, TextHTML)
c.Response.committed = false
c.response.committed = false
if he := c.HTML(http.StatusOK, "Hello, <strong>World!</strong>"); he != nil {
t.Errorf("html %v", he.Error)
}

// Redirect
c.Response.committed = false
c.response.committed = false
c.Redirect(http.StatusMovedPermanently, "http://labstack.github.io/echo")
}
58 changes: 32 additions & 26 deletions echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
"strings"
"sync"

"github.com/bradfitz/http2"
"github.com/mattn/go-colorable"
"golang.org/x/net/websocket"
"github.com/bradfitz/http2"
)

type (
Expand All @@ -34,8 +34,8 @@ type (
debug bool
}
HTTPError struct {
Code int
Message string
code int
message string
}
Middleware interface{}
MiddlewareFunc func(HandlerFunc) HandlerFunc
Expand Down Expand Up @@ -123,15 +123,21 @@ var (
)

func NewHTTPError(code int, msg ...string) *HTTPError {
he := &HTTPError{Code: code, Message: http.StatusText(code)}
he := &HTTPError{code: code, message: http.StatusText(code)}
for _, m := range msg {
he.Message = m
he.message = m
}
return he
}

// Code returns code.
func (e *HTTPError) Code() int {
return e.code
}

// Error returns message.
func (e *HTTPError) Error() string {
return e.Message
return e.message
}

// New creates an Echo instance.
Expand All @@ -157,13 +163,13 @@ func New() (e *Echo) {
code := http.StatusInternalServerError
msg := http.StatusText(code)
if he, ok := err.(*HTTPError); ok {
code = he.Code
msg = he.Message
code = he.code
msg = he.message
}
if e.Debug() {
msg = err.Error()
}
http.Error(c.Response, msg, code)
http.Error(c.response, msg, code)
})
e.SetBinder(func(r *http.Request, v interface{}) error {
ct := r.Header.Get(ContentType)
Expand Down Expand Up @@ -283,12 +289,12 @@ func (e *Echo) WebSocket(path string, h HandlerFunc) {
e.Get(path, func(c *Context) (err error) {
wss := websocket.Server{
Handler: func(ws *websocket.Conn) {
c.Socket = ws
c.Response.status = http.StatusSwitchingProtocols
c.socket = ws
c.response.status = http.StatusSwitchingProtocols
err = h(c)
},
}
wss.ServeHTTP(c.Response.writer, c.Request)
wss.ServeHTTP(c.response.writer, c.request)
return err
})
}
Expand All @@ -313,15 +319,15 @@ func (e *Echo) Favicon(file string) {
func (e *Echo) Static(path, root string) {
fs := http.StripPrefix(path, http.FileServer(http.Dir(root)))
e.Get(path+"*", func(c *Context) error {
fs.ServeHTTP(c.Response, c.Request)
fs.ServeHTTP(c.response, c.request)
return nil
})
}

// ServeFile serves a file.
func (e *Echo) ServeFile(path, file string) {
e.Get(path, func(c *Context) error {
http.ServeFile(c.Response, c.Request, file)
http.ServeFile(c.response, c.request, file)
return nil
})
}
Expand Down Expand Up @@ -399,17 +405,17 @@ func (e *Echo) RunTLSServer(srv *http.Server, certFile, keyFile string) {
e.run(srv, certFile, keyFile)
}

func (e *Echo) run(s *http.Server, f ...string) {
func (e *Echo) run(s *http.Server, files ...string) {
s.Handler = e
if e.http2 {
http2.ConfigureServer(s, nil)
}
if len(f) == 0 {
if len(files) == 0 {
log.Fatal(s.ListenAndServe())
} else if len(f) == 2 {
log.Fatal(s.ListenAndServeTLS(f[0], f[1]))
} else if len(files) == 2 {
log.Fatal(s.ListenAndServeTLS(files[0], files[1]))
} else {
log.Fatal("echo: invalid TLS configuration")
log.Fatal("echo => invalid TLS configuration")
}
}

Expand All @@ -428,10 +434,10 @@ func wrapMiddleware(m Middleware) MiddlewareFunc {
return func(h HandlerFunc) HandlerFunc {
return func(c *Context) (err error) {
m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c.Response.writer = w
c.Request = r
c.response.writer = w
c.request = r
err = h(c)
})).ServeHTTP(c.Response.writer, c.Request)
})).ServeHTTP(c.response.writer, c.request)
return
}
}
Expand Down Expand Up @@ -462,8 +468,8 @@ func wrapHandlerFuncMW(m HandlerFunc) MiddlewareFunc {
func wrapHTTPHandlerFuncMW(m http.HandlerFunc) MiddlewareFunc {
return func(h HandlerFunc) HandlerFunc {
return func(c *Context) error {
if !c.Response.committed {
m.ServeHTTP(c.Response.writer, c.Request)
if !c.response.committed {
m.ServeHTTP(c.response.writer, c.request)
}
return h(c)
}
Expand All @@ -479,12 +485,12 @@ func wrapHandler(h Handler) HandlerFunc {
return h
case http.Handler, http.HandlerFunc:
return func(c *Context) error {
h.(http.Handler).ServeHTTP(c.Response, c.Request)
h.(http.Handler).ServeHTTP(c.response, c.request)
return nil
}
case func(http.ResponseWriter, *http.Request):
return func(c *Context) error {
h(c.Response, c.Request)
h(c.response, c.request)
return nil
}
default:
Expand Down
2 changes: 1 addition & 1 deletion echo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func TestEchoMethod(t *testing.T) {
func TestWebSocket(t *testing.T) {
e := New()
e.WebSocket("/ws", func(c *Context) error {
c.Socket.Write([]byte("test"))
c.socket.Write([]byte("test"))
return nil
})
srv := httptest.NewServer(e)
Expand Down
2 changes: 1 addition & 1 deletion middleware/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
// For invalid credentials, it sends "401 - Unauthorized" response.
func BasicAuth(fn AuthFunc) echo.HandlerFunc {
return func(c *echo.Context) error {
auth := c.Request.Header.Get(echo.Authorization)
auth := c.Request().Header.Get(echo.Authorization)
i := 0
code := http.StatusBadRequest

Expand Down
16 changes: 8 additions & 8 deletions middleware/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func TestBasicAuth(t *testing.T) {
he := ba(c).(*echo.HTTPError)
if ba(c) == nil {
t.Error("expected `fail`, with incorrect password.")
} else if he.Code != http.StatusUnauthorized {
t.Errorf("expected status `401`, got %d", he.Code)
} else if he.Code() != http.StatusUnauthorized {
t.Errorf("expected status `401`, got %d", he.Code())
}

// Empty Authorization header
Expand All @@ -58,8 +58,8 @@ func TestBasicAuth(t *testing.T) {
he = ba(c).(*echo.HTTPError)
if he == nil {
t.Error("expected `fail`, with empty Authorization header.")
} else if he.Code != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code)
} else if he.Code() != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code())
}

// Invalid Authorization header
Expand All @@ -69,8 +69,8 @@ func TestBasicAuth(t *testing.T) {
he = ba(c).(*echo.HTTPError)
if he == nil {
t.Error("expected `fail`, with invalid Authorization header.")
} else if he.Code != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code)
} else if he.Code() != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code())
}

// Invalid scheme
Expand All @@ -80,7 +80,7 @@ func TestBasicAuth(t *testing.T) {
he = ba(c).(*echo.HTTPError)
if he == nil {
t.Error("expected `fail`, with invalid scheme.")
} else if he.Code != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code)
} else if he.Code() != http.StatusBadRequest {
t.Errorf("expected status `400`, got %d", he.Code())
}
}
Loading

0 comments on commit bf85c56

Please sign in to comment.