github.com/sotirispl/buffalo@v0.11.1/handler.go (about)

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