package sliderule import ( "context" "tildegit.org/tjp/sliderule/internal/types" ) type Handler = types.Handler type Middleware = types.Middleware // HandlerFunc is a wrapper to allow using a function as a Handler. func HandlerFunc(f func(context.Context, *Request) *Response) Handler { return types.HandlerFunc(f) } // FallthroughHandler builds a handler which tries multiple child handlers. // // The returned handler will invoke each of the passed-in handlers in order, // stopping when it receives a non-nil response. func FallthroughHandler(handlers ...Handler) Handler { return HandlerFunc(func(ctx context.Context, request *Request) *Response { for _, handler := range handlers { if response := handler.Handle(ctx, request); response != nil { return response } } return nil }) } // Filter builds a middleware which only calls the wrapped Handler under a condition. // // When the condition function returns false it instead invokes the test-failure // handler. The failure handler may also be nil, in which case the final handler will // return a nil response whenever the condition fails. func Filter( condition func(context.Context, *Request) bool, failure Handler, ) Middleware { return func(success Handler) Handler { return HandlerFunc(func(ctx context.Context, request *Request) *Response { if condition(ctx, request) { return success.Handle(ctx, request) } if failure == nil { return nil } return failure.Handle(ctx, request) }) } } // VirtualHosts builds a handler which dispatches to site handlers by hostname. // // The 'catchall' argument may be used to specify a handler for use when no hostname // match is found. If the catchall is nil and no match is found, the VirtualHosts // handler returns a nil response. func VirtualHosts(hosts map[string]Handler, catchall Handler) Handler { return HandlerFunc(func(ctx context.Context, request *Request) *Response { if h := hosts[request.Hostname()]; h != nil { return h.Handle(ctx, request) } if catchall != nil { return catchall.Handle(ctx, request) } return nil }) }