github.com/segakazzz/buffalo@v0.16.22-0.20210119082501-1f52048d3feb/app.go (about)

     1  package buffalo
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"sync"
     7  
     8  	"github.com/gobuffalo/envy"
     9  	"github.com/gorilla/mux"
    10  )
    11  
    12  // App is where it all happens! It holds on to options,
    13  // the underlying router, the middleware, and more.
    14  // Without an App you can't do much!
    15  type App struct {
    16  	Options
    17  	// Middleware returns the current MiddlewareStack for the App/Group.
    18  	Middleware    *MiddlewareStack `json:"-"`
    19  	ErrorHandlers ErrorHandlers    `json:"-"`
    20  	router        *mux.Router
    21  	moot          *sync.RWMutex
    22  	routes        RouteList
    23  	root          *App
    24  	children      []*App
    25  	filepaths     []string
    26  
    27  	// Routenamer for the app. This field provides the ability to override the
    28  	// base route namer for something more specific to the app.
    29  	RouteNamer RouteNamer
    30  }
    31  
    32  // Muxer returns the underlying mux router to allow
    33  // for advance configurations
    34  func (a *App) Muxer() *mux.Router {
    35  	return a.router
    36  }
    37  
    38  // New returns a new instance of App and adds some sane, and useful, defaults.
    39  func New(opts Options) *App {
    40  	LoadPlugins()
    41  	envy.Load()
    42  
    43  	opts = optionsWithDefaults(opts)
    44  
    45  	a := &App{
    46  		Options: opts,
    47  		ErrorHandlers: ErrorHandlers{
    48  			http.StatusNotFound:            defaultErrorHandler,
    49  			http.StatusInternalServerError: defaultErrorHandler,
    50  		},
    51  		router:   mux.NewRouter(),
    52  		moot:     &sync.RWMutex{},
    53  		routes:   RouteList{},
    54  		children: []*App{},
    55  
    56  		RouteNamer: baseRouteNamer{},
    57  	}
    58  
    59  	dem := a.defaultErrorMiddleware
    60  	a.Middleware = newMiddlewareStack(dem)
    61  
    62  	notFoundHandler := func(errorf string, code int) http.HandlerFunc {
    63  		return func(res http.ResponseWriter, req *http.Request) {
    64  			c := a.newContext(RouteInfo{}, res, req)
    65  			err := fmt.Errorf(errorf, req.Method, req.URL.Path)
    66  			_ = a.ErrorHandlers.Get(code)(code, err, c)
    67  
    68  		}
    69  	}
    70  
    71  	a.router.NotFoundHandler = notFoundHandler("path not found: %s %s", http.StatusNotFound)
    72  	a.router.MethodNotAllowedHandler = notFoundHandler("method not found: %s %s", http.StatusMethodNotAllowed)
    73  
    74  	if a.MethodOverride == nil {
    75  		a.MethodOverride = MethodOverride
    76  	}
    77  	a.Use(a.PanicHandler)
    78  	a.Use(RequestLogger)
    79  	a.Use(sessionSaver)
    80  
    81  	return a
    82  }