github.com/gotstago/buffalo@v0.9.5/handler.go (about)

     1  package buffalo
     2  
     3  import (
     4  	"net/http"
     5  
     6  	gcontext "github.com/gorilla/context"
     7  	"github.com/gorilla/mux"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // Handler is the basis for all of Buffalo. A Handler
    12  // will be given a Context interface that represents the
    13  // give request/response. It is the responsibility of the
    14  // Handler to handle the request/response correctly. This
    15  // could mean rendering a template, JSON, etc... or it could
    16  // mean returning an error.
    17  /*
    18  	func (c Context) error {
    19  		return c.Render(200, render.String("Hello World!"))
    20  	}
    21  
    22  	func (c Context) error {
    23  		return c.Redirect(301, "http://github.com/gobuffalo/buffalo")
    24  	}
    25  
    26  	func (c Context) error {
    27  		return c.Error(422, errors.New("oops!!"))
    28  	}
    29  */
    30  type Handler func(Context) error
    31  
    32  func (a *App) newContext(info RouteInfo, res http.ResponseWriter, req *http.Request) Context {
    33  	ws := res.(*Response)
    34  	params := req.URL.Query()
    35  	vars := mux.Vars(req)
    36  	for k, v := range vars {
    37  		params.Set(k, v)
    38  	}
    39  
    40  	session := a.getSession(req, ws)
    41  
    42  	contextData := map[string]interface{}{
    43  		"app":           a,
    44  		"env":           a.Env,
    45  		"routes":        a.Routes(),
    46  		"current_route": info,
    47  		"current_path":  req.URL.Path,
    48  	}
    49  
    50  	for _, route := range a.Routes() {
    51  		cRoute := route
    52  		contextData[cRoute.PathName] = cRoute.BuildPathHelper()
    53  	}
    54  
    55  	return &DefaultContext{
    56  		Context:  req.Context(),
    57  		response: ws,
    58  		request:  req,
    59  		params:   params,
    60  		logger:   a.Logger,
    61  		session:  session,
    62  		flash:    newFlash(session),
    63  		data:     contextData,
    64  	}
    65  }
    66  
    67  func (info RouteInfo) ServeHTTP(res http.ResponseWriter, req *http.Request) {
    68  	defer gcontext.Clear(req)
    69  	a := info.App
    70  
    71  	c := a.newContext(info, res, req)
    72  
    73  	defer c.Flash().persist(c.Session())
    74  
    75  	err := a.Middleware.handler(info)(c)
    76  
    77  	if err != nil {
    78  		status := 500
    79  		// unpack root cause and check for HTTPError
    80  		cause := errors.Cause(err)
    81  		httpError, ok := cause.(HTTPError)
    82  		if ok {
    83  			status = httpError.Status
    84  		}
    85  		eh := a.ErrorHandlers.Get(status)
    86  		err = eh(status, err, c)
    87  		if err != nil {
    88  			// things have really hit the fan if we're here!!
    89  			a.Logger.Error(err)
    90  			c.Response().WriteHeader(500)
    91  			c.Response().Write([]byte(err.Error()))
    92  		}
    93  	}
    94  }