@@ -14,6 +14,7 @@ import (
1414 "sync"
1515
1616 "github.com/mattn/go-colorable"
17+ "golang.org/x/net/websocket"
1718)
1819
1920type (
@@ -33,24 +34,23 @@ type (
3334 HTTPError struct {
3435 Code int
3536 Message string
36- Error error
3737 }
3838 Middleware interface {}
3939 MiddlewareFunc func (HandlerFunc ) HandlerFunc
4040 Handler interface {}
41- HandlerFunc func (* Context ) * HTTPError
41+ HandlerFunc func (* Context ) error
4242
4343 // HTTPErrorHandler is a centralized HTTP error handler.
44- HTTPErrorHandler func (* HTTPError , * Context )
44+ HTTPErrorHandler func (error , * Context )
4545
46- BindFunc func (* http.Request , interface {}) * HTTPError
46+ BindFunc func (* http.Request , interface {}) error
4747
4848 // Renderer is the interface that wraps the Render method.
4949 //
5050 // Render renders the HTML template with given name and specified data.
5151 // It writes the output to w.
5252 Renderer interface {
53- Render (w io.Writer , name string , data interface {}) * HTTPError
53+ Render (w io.Writer , name string , data interface {}) error
5454 }
5555)
5656
@@ -120,6 +120,10 @@ var (
120120 RendererNotRegistered = errors .New ("echo ⇒ renderer not registered" )
121121)
122122
123+ func (e * HTTPError ) Error () string {
124+ return e .Message
125+ }
126+
123127// New creates an Echo instance.
124128func New () (e * Echo ) {
125129 e = & Echo {
@@ -135,33 +139,30 @@ func New() (e *Echo) {
135139 //----------
136140
137141 e .SetMaxParam (5 )
138- e .notFoundHandler = func (c * Context ) * HTTPError {
142+ e .notFoundHandler = func (c * Context ) error {
139143 return & HTTPError {Code : http .StatusNotFound }
140144 }
141- e .SetHTTPErrorHandler (func (he * HTTPError , c * Context ) {
142- if he . Code == 0 {
143- he . Code = http .StatusInternalServerError
144- }
145- if he . Message == "" {
146- he . Message = http . StatusText ( he .Code )
145+ e .SetHTTPErrorHandler (func (err error , c * Context ) {
146+ code := http . StatusInternalServerError
147+ msg : = http .StatusText ( code )
148+ if he , ok := err .( * HTTPError ); ok {
149+ code = he . Code
150+ msg = he .Message
147151 }
148- if e .debug && he . Error != nil {
149- he . Message = he . Error .Error ()
152+ if e .Debug () {
153+ msg = err .Error ()
150154 }
151- http .Error (c .Response , he . Message , he . Code )
155+ http .Error (c .Response , msg , code )
152156 })
153- e .SetBinder (func (r * http.Request , v interface {}) * HTTPError {
157+ e .SetBinder (func (r * http.Request , v interface {}) error {
154158 ct := r .Header .Get (ContentType )
155159 err := UnsupportedMediaType
156160 if strings .HasPrefix (ct , ApplicationJSON ) {
157161 err = json .NewDecoder (r .Body ).Decode (v )
158162 } else if strings .HasPrefix (ct , ApplicationForm ) {
159163 err = nil
160164 }
161- if err != nil {
162- return & HTTPError {Error : err }
163- }
164- return nil
165+ return err
165166 })
166167 return
167168}
@@ -261,6 +262,21 @@ func (e *Echo) Trace(path string, h Handler) {
261262 e .add (TRACE , path , h )
262263}
263264
265+ // WebSocket adds a WebSocket route > handler to the router.
266+ func (e * Echo ) WebSocket (path string , h HandlerFunc ) {
267+ e .Get (path , func (c * Context ) * HTTPError {
268+ wss := websocket.Server {
269+ Handler : func (ws * websocket.Conn ) {
270+ c .Socket = ws
271+ c .Response .status = http .StatusSwitchingProtocols
272+ h (c )
273+ },
274+ }
275+ wss .ServeHTTP (c .Response .writer , c .Request )
276+ return nil
277+ })
278+ }
279+
264280func (e * Echo ) add (method , path string , h Handler ) {
265281 key := runtime .FuncForPC (reflect .ValueOf (h ).Pointer ()).Name ()
266282 e .uris [key ] = path
@@ -280,15 +296,15 @@ func (e *Echo) Favicon(file string) {
280296// Static serves static files.
281297func (e * Echo ) Static (path , root string ) {
282298 fs := http .StripPrefix (path , http .FileServer (http .Dir (root )))
283- e .Get (path + "*" , func (c * Context ) * HTTPError {
299+ e .Get (path + "*" , func (c * Context ) error {
284300 fs .ServeHTTP (c .Response , c .Request )
285301 return nil
286302 })
287303}
288304
289305// ServeFile serves a file.
290306func (e * Echo ) ServeFile (path , file string ) {
291- e .Get (path , func (c * Context ) * HTTPError {
307+ e .Get (path , func (c * Context ) error {
292308 http .ServeFile (c .Response , c .Request , file )
293309 return nil
294310 })
@@ -376,16 +392,16 @@ func wrapMiddleware(m Middleware) MiddlewareFunc {
376392 return m
377393 case HandlerFunc :
378394 return wrapHandlerFuncMW (m )
379- case func (* Context ) * HTTPError :
395+ case func (* Context ) error :
380396 return wrapHandlerFuncMW (m )
381397 case func (http.Handler ) http.Handler :
382398 return func (h HandlerFunc ) HandlerFunc {
383- return func (c * Context ) (he * HTTPError ) {
399+ return func (c * Context ) (err error ) {
384400 m (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
385- c .Response .Writer = w
401+ c .Response .writer = w
386402 c .Request = r
387- he = h (c )
388- })).ServeHTTP (c .Response .Writer , c .Request )
403+ err = h (c )
404+ })).ServeHTTP (c .Response .writer , c .Request )
389405 return
390406 }
391407 }
@@ -403,9 +419,9 @@ func wrapMiddleware(m Middleware) MiddlewareFunc {
403419// Wraps HandlerFunc middleware
404420func wrapHandlerFuncMW (m HandlerFunc ) MiddlewareFunc {
405421 return func (h HandlerFunc ) HandlerFunc {
406- return func (c * Context ) * HTTPError {
407- if he := m (c ); he != nil {
408- return he
422+ return func (c * Context ) error {
423+ if err := m (c ); err != nil {
424+ return err
409425 }
410426 return h (c )
411427 }
@@ -415,9 +431,9 @@ func wrapHandlerFuncMW(m HandlerFunc) MiddlewareFunc {
415431// Wraps http.HandlerFunc middleware
416432func wrapHTTPHandlerFuncMW (m http.HandlerFunc ) MiddlewareFunc {
417433 return func (h HandlerFunc ) HandlerFunc {
418- return func (c * Context ) * HTTPError {
434+ return func (c * Context ) error {
419435 if ! c .Response .committed {
420- m .ServeHTTP (c .Response .Writer , c .Request )
436+ m .ServeHTTP (c .Response .writer , c .Request )
421437 }
422438 return h (c )
423439 }
@@ -429,15 +445,15 @@ func wrapHandler(h Handler) HandlerFunc {
429445 switch h := h .(type ) {
430446 case HandlerFunc :
431447 return h
432- case func (* Context ) * HTTPError :
448+ case func (* Context ) error :
433449 return h
434450 case http.Handler , http.HandlerFunc :
435- return func (c * Context ) * HTTPError {
451+ return func (c * Context ) error {
436452 h .(http.Handler ).ServeHTTP (c .Response , c .Request )
437453 return nil
438454 }
439455 case func (http.ResponseWriter , * http.Request ):
440- return func (c * Context ) * HTTPError {
456+ return func (c * Context ) error {
441457 h (c .Response , c .Request )
442458 return nil
443459 }
0 commit comments