@@ -279,61 +279,89 @@ func splitRoutes(routeStr string) (*route, error) {
279
279
return nil , ErrRouteStringFormat
280
280
}
281
281
282
+ type middlewareTyp int
283
+
284
+ const (
285
+ plainMiddleware middlewareTyp = iota
286
+ ctxMiddleware
287
+ )
288
+
289
+ type middleware struct {
290
+ typ middlewareTyp
291
+ value interface {}
292
+ }
293
+
294
+ func (m * middleware ) ToHandler (ctx * Context ) func (http.Handler ) http.Handler {
295
+ if m .typ == plainMiddleware {
296
+ return m .value .(func (http.Handler ) http.Handler )
297
+ }
298
+ fn := m .value .(func (* Context ) error )
299
+ return func (h http.Handler ) http.Handler {
300
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
301
+ err := fn (ctx )
302
+ if err != nil {
303
+ return
304
+ }
305
+ h .ServeHTTP (w , r )
306
+ })
307
+ }
308
+ }
309
+
282
310
// add registers controller ctrl, using activeRoute. If middlewares are provided, utron uses
283
311
// alice package to chain middlewares.
284
312
func (r * Router ) add (activeRoute * route , ctrl Controller , middlewares ... interface {}) error {
285
- chain := alice . New () // alice on chains
313
+ var m [] * middleware
286
314
if len (middlewares ) > 0 {
287
- var m []alice.Constructor
288
315
for _ , v := range middlewares {
289
316
switch v .(type ) {
290
317
case func (http.Handler ) http.Handler :
291
- m = append (m , v .(func (http.Handler ) http.Handler ))
318
+ m = append (m , & middleware {
319
+ typ : plainMiddleware ,
320
+ value : v ,
321
+ })
292
322
case func (* Context ) error :
293
-
294
- // wrap func(*Context)error to a func(http.Handler)http.Handler
295
- //
296
- //TODO put this into a separate function?
297
- ctxMiddleware := func (h http.Handler ) http.Handler {
298
- return http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
299
- ctx := NewContext (w , req )
300
- r .prepareContext (ctx )
301
- err := v .(func (* Context ) error )(ctx )
302
- if err != nil {
303
- cerr := ctx .Commit ()
304
- if cerr != nil {
305
- logThis .Errors (req .URL .Path , " " , cerr .Error ())
306
- }
307
- return
308
- }
309
- h .ServeHTTP (ctx .Response (), ctx .Request ())
310
- })
311
- }
312
-
313
- m = append (m , ctxMiddleware )
323
+ m = append (m , & middleware {
324
+ typ : ctxMiddleware ,
325
+ value : v ,
326
+ })
314
327
315
328
default :
316
329
return fmt .Errorf ("unsupported middleware %v" , v )
317
330
}
318
331
}
319
- chain = alice .New (m ... )
320
332
}
321
-
322
333
// register methods if any
323
334
if len (activeRoute .methods ) > 0 {
324
335
r .HandleFunc (activeRoute .pattern , func (w http.ResponseWriter , req * http.Request ) {
325
- chain .ThenFunc (r .wrapController (activeRoute .fn , ctrl )).ServeHTTP (w , req )
336
+ ctx := NewContext (w , req )
337
+ r .prepareContext (ctx )
338
+ chain := chainMiddleware (ctx , m ... )
339
+ chain .ThenFunc (r .wrapController (ctx , activeRoute .fn , ctrl )).ServeHTTP (w , req )
326
340
}).Methods (activeRoute .methods ... )
327
341
return nil
328
342
}
329
-
330
343
r .HandleFunc (activeRoute .pattern , func (w http.ResponseWriter , req * http.Request ) {
331
- chain .ThenFunc (r .wrapController (activeRoute .fn , ctrl )).ServeHTTP (w , req )
344
+ ctx := NewContext (w , req )
345
+ r .prepareContext (ctx )
346
+ chain := chainMiddleware (ctx , m ... )
347
+ chain .ThenFunc (r .wrapController (ctx , activeRoute .fn , ctrl )).ServeHTTP (w , req )
332
348
})
333
349
334
350
return nil
335
351
}
336
352
353
+ func chainMiddleware (ctx * Context , wares ... * middleware ) alice.Chain {
354
+ if len (wares ) > 0 {
355
+ var m []alice.Constructor
356
+ for _ , v := range wares {
357
+ m = append (m , v .ToHandler (ctx ))
358
+ }
359
+ return alice .New (m ... )
360
+ }
361
+ return alice .New ()
362
+
363
+ }
364
+
337
365
// prepareContext sets view,config and model on the ctx.
338
366
func (r * Router ) prepareContext (ctx * Context ) {
339
367
if r .app != nil {
@@ -350,9 +378,7 @@ func (r *Router) prepareContext(ctx *Context) {
350
378
}
351
379
352
380
// executes the method fn on Controller ctrl, it sets context.
353
- func (r * Router ) handleController (w http.ResponseWriter , req * http.Request , fn string , ctrl Controller ) {
354
- ctx := NewContext (w , req )
355
- r .prepareContext (ctx )
381
+ func (r * Router ) handleController (ctx * Context , fn string , ctrl Controller ) {
356
382
ctrl .New (ctx )
357
383
358
384
// execute the method
@@ -371,9 +397,9 @@ func (r *Router) handleController(w http.ResponseWriter, req *http.Request, fn s
371
397
}
372
398
373
399
// wrapController wraps a controller ctrl with method fn, and returns http.HandleFunc
374
- func (r * Router ) wrapController (fn string , ctrl Controller ) func (http.ResponseWriter , * http.Request ) {
400
+ func (r * Router ) wrapController (ctx * Context , fn string , ctrl Controller ) func (http.ResponseWriter , * http.Request ) {
375
401
return func (w http.ResponseWriter , req * http.Request ) {
376
- r .handleController (w , req , fn , ctrl )
402
+ r .handleController (ctx , fn , ctrl )
377
403
}
378
404
}
379
405
0 commit comments