123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package wisp
- import (
- "context"
- "net/http"
- "strings"
- "github.com/julienschmidt/httprouter"
- )
- type Wisp struct {
- router *httprouter.Router
- errorHandler ErrorHandler
- middlewares []Middleware
- }
- func New() *Wisp {
- return &Wisp{
- router: httprouter.New(),
- errorHandler: defaultErrorHandler,
- middlewares: []Middleware{},
- }
- }
- func (w *Wisp) SetErrorHandler(errorHandler ErrorHandler) {
- w.errorHandler = errorHandler
- }
- func (w *Wisp) Use(m ...Middleware) {
- w.middlewares = append(w.middlewares, m...)
- }
- func (w *Wisp) Group(prefix string, middlewares ...Middleware) *Group {
- return &Group{
- prefix: prefix,
- parent: w,
- middlewares: middlewares,
- }
- }
- func (w *Wisp) GET(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodGet, path, h, mws...)
- }
- func (w *Wisp) POST(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodPost, path, h, mws...)
- }
- func (w *Wisp) PUT(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodPut, path, h, mws...)
- }
- func (w *Wisp) DELETE(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodDelete, path, h, mws...)
- }
- func (w *Wisp) PATCH(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodPatch, path, h, mws...)
- }
- func (w *Wisp) OPTIONS(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodOptions, path, h, mws...)
- }
- func (w *Wisp) HEAD(path string, h Handler, mws ...Middleware) {
- w.handle(http.MethodHead, path, h, mws...)
- }
- func (w *Wisp) Static(path, root string) {
- if !strings.HasSuffix(path, "/*filepath") {
- if strings.HasSuffix(path, "/") {
- path += "*filepath"
- } else {
- path += "/*filepath"
- }
- }
- fileServer := http.StripPrefix(strings.TrimSuffix(path, "/*filepath"), http.FileServer(http.Dir(root)))
- w.router.GET(path, func(wr http.ResponseWriter, r *http.Request, _ httprouter.Params) {
- fileServer.ServeHTTP(wr, r)
- })
- }
- func (w *Wisp) Start(addr string) error {
- return http.ListenAndServe(addr, w.router)
- }
- func (w *Wisp) StartWithTLS(addr, certFile, keyFile string) error {
- return http.ListenAndServeTLS(addr, certFile, keyFile, w.router)
- }
- func (w *Wisp) handle(method, path string, h Handler, mws ...Middleware) {
- all := append(w.middlewares, mws...)
- final := w.chainMiddlewares(h, all)
- w.register(method, path, w.makeHTTPRouterHandler(final))
- }
- func (w *Wisp) register(method, path string, h httprouter.Handle) {
- switch method {
- case http.MethodGet:
- w.router.GET(path, h)
- case http.MethodPost:
- w.router.POST(path, h)
- case http.MethodPut:
- w.router.PUT(path, h)
- case http.MethodDelete:
- w.router.DELETE(path, h)
- case http.MethodPatch:
- w.router.PATCH(path, h)
- case http.MethodOptions:
- w.router.OPTIONS(path, h)
- case http.MethodHead:
- w.router.HEAD(path, h)
- }
- }
- func (w *Wisp) chainMiddlewares(h Handler, mws []Middleware) Handler {
- for i := len(mws) - 1; i >= 0; i-- {
- h = mws[i](h)
- }
- return h
- }
- func (w *Wisp) makeHTTPRouterHandler(h Handler) httprouter.Handle {
- return func(wr http.ResponseWriter, r *http.Request, p httprouter.Params) {
- context := &Context{
- response: wr,
- request: r,
- params: p,
- ctx: context.Background(),
- }
- if err := h(context); err != nil {
- w.errorHandler(err, context)
- }
- }
- }
|