@@ -14,6 +14,7 @@ import (
14
14
"sync"
15
15
16
16
"github.com/mattn/go-colorable"
17
+ "golang.org/x/net/websocket"
17
18
)
18
19
19
20
type (
@@ -33,24 +34,23 @@ type (
33
34
HTTPError struct {
34
35
Code int
35
36
Message string
36
- Error error
37
37
}
38
38
Middleware interface {}
39
39
MiddlewareFunc func (HandlerFunc ) HandlerFunc
40
40
Handler interface {}
41
- HandlerFunc func (* Context ) * HTTPError
41
+ HandlerFunc func (* Context ) error
42
42
43
43
// HTTPErrorHandler is a centralized HTTP error handler.
44
- HTTPErrorHandler func (* HTTPError , * Context )
44
+ HTTPErrorHandler func (error , * Context )
45
45
46
- BindFunc func (* http.Request , interface {}) * HTTPError
46
+ BindFunc func (* http.Request , interface {}) error
47
47
48
48
// Renderer is the interface that wraps the Render method.
49
49
//
50
50
// Render renders the HTML template with given name and specified data.
51
51
// It writes the output to w.
52
52
Renderer interface {
53
- Render (w io.Writer , name string , data interface {}) * HTTPError
53
+ Render (w io.Writer , name string , data interface {}) error
54
54
}
55
55
)
56
56
@@ -120,6 +120,10 @@ var (
120
120
RendererNotRegistered = errors .New ("echo ⇒ renderer not registered" )
121
121
)
122
122
123
+ func (e * HTTPError ) Error () string {
124
+ return e .Message
125
+ }
126
+
123
127
// New creates an Echo instance.
124
128
func New () (e * Echo ) {
125
129
e = & Echo {
@@ -135,33 +139,30 @@ func New() (e *Echo) {
135
139
//----------
136
140
137
141
e .SetMaxParam (5 )
138
- e .notFoundHandler = func (c * Context ) * HTTPError {
142
+ e .notFoundHandler = func (c * Context ) error {
139
143
return & HTTPError {Code : http .StatusNotFound }
140
144
}
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
147
151
}
148
- if e .debug && he . Error != nil {
149
- he . Message = he . Error .Error ()
152
+ if e .Debug () {
153
+ msg = err .Error ()
150
154
}
151
- http .Error (c .Response , he . Message , he . Code )
155
+ http .Error (c .Response , msg , code )
152
156
})
153
- e .SetBinder (func (r * http.Request , v interface {}) * HTTPError {
157
+ e .SetBinder (func (r * http.Request , v interface {}) error {
154
158
ct := r .Header .Get (ContentType )
155
159
err := UnsupportedMediaType
156
160
if strings .HasPrefix (ct , ApplicationJSON ) {
157
161
err = json .NewDecoder (r .Body ).Decode (v )
158
162
} else if strings .HasPrefix (ct , ApplicationForm ) {
159
163
err = nil
160
164
}
161
- if err != nil {
162
- return & HTTPError {Error : err }
163
- }
164
- return nil
165
+ return err
165
166
})
166
167
return
167
168
}
@@ -261,6 +262,21 @@ func (e *Echo) Trace(path string, h Handler) {
261
262
e .add (TRACE , path , h )
262
263
}
263
264
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
+
264
280
func (e * Echo ) add (method , path string , h Handler ) {
265
281
key := runtime .FuncForPC (reflect .ValueOf (h ).Pointer ()).Name ()
266
282
e .uris [key ] = path
@@ -280,15 +296,15 @@ func (e *Echo) Favicon(file string) {
280
296
// Static serves static files.
281
297
func (e * Echo ) Static (path , root string ) {
282
298
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 {
284
300
fs .ServeHTTP (c .Response , c .Request )
285
301
return nil
286
302
})
287
303
}
288
304
289
305
// ServeFile serves a file.
290
306
func (e * Echo ) ServeFile (path , file string ) {
291
- e .Get (path , func (c * Context ) * HTTPError {
307
+ e .Get (path , func (c * Context ) error {
292
308
http .ServeFile (c .Response , c .Request , file )
293
309
return nil
294
310
})
@@ -376,16 +392,16 @@ func wrapMiddleware(m Middleware) MiddlewareFunc {
376
392
return m
377
393
case HandlerFunc :
378
394
return wrapHandlerFuncMW (m )
379
- case func (* Context ) * HTTPError :
395
+ case func (* Context ) error :
380
396
return wrapHandlerFuncMW (m )
381
397
case func (http.Handler ) http.Handler :
382
398
return func (h HandlerFunc ) HandlerFunc {
383
- return func (c * Context ) (he * HTTPError ) {
399
+ return func (c * Context ) (err error ) {
384
400
m (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
385
- c .Response .Writer = w
401
+ c .Response .writer = w
386
402
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 )
389
405
return
390
406
}
391
407
}
@@ -403,9 +419,9 @@ func wrapMiddleware(m Middleware) MiddlewareFunc {
403
419
// Wraps HandlerFunc middleware
404
420
func wrapHandlerFuncMW (m HandlerFunc ) MiddlewareFunc {
405
421
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
409
425
}
410
426
return h (c )
411
427
}
@@ -415,9 +431,9 @@ func wrapHandlerFuncMW(m HandlerFunc) MiddlewareFunc {
415
431
// Wraps http.HandlerFunc middleware
416
432
func wrapHTTPHandlerFuncMW (m http.HandlerFunc ) MiddlewareFunc {
417
433
return func (h HandlerFunc ) HandlerFunc {
418
- return func (c * Context ) * HTTPError {
434
+ return func (c * Context ) error {
419
435
if ! c .Response .committed {
420
- m .ServeHTTP (c .Response .Writer , c .Request )
436
+ m .ServeHTTP (c .Response .writer , c .Request )
421
437
}
422
438
return h (c )
423
439
}
@@ -429,15 +445,15 @@ func wrapHandler(h Handler) HandlerFunc {
429
445
switch h := h .(type ) {
430
446
case HandlerFunc :
431
447
return h
432
- case func (* Context ) * HTTPError :
448
+ case func (* Context ) error :
433
449
return h
434
450
case http.Handler , http.HandlerFunc :
435
- return func (c * Context ) * HTTPError {
451
+ return func (c * Context ) error {
436
452
h .(http.Handler ).ServeHTTP (c .Response , c .Request )
437
453
return nil
438
454
}
439
455
case func (http.ResponseWriter , * http.Request ):
440
- return func (c * Context ) * HTTPError {
456
+ return func (c * Context ) error {
441
457
h (c .Response , c .Request )
442
458
return nil
443
459
}
0 commit comments