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

     1  package buffalo
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/url"
     7  	"sync"
     8  
     9  	"github.com/gobuffalo/buffalo/binding"
    10  	"github.com/gobuffalo/buffalo/render"
    11  	"github.com/gorilla/mux"
    12  	"github.com/segakazzz/buffalo/internal/httpx"
    13  )
    14  
    15  // Context holds on to information as you
    16  // pass it down through middleware, Handlers,
    17  // templates, etc... It strives to make your
    18  // life a happier one.
    19  type Context interface {
    20  	context.Context
    21  	Response() http.ResponseWriter
    22  	Request() *http.Request
    23  	Session() *Session
    24  	Cookies() *Cookies
    25  	Params() ParamValues
    26  	Param(string) string
    27  	Set(string, interface{})
    28  	LogField(string, interface{})
    29  	LogFields(map[string]interface{})
    30  	Logger() Logger
    31  	Bind(interface{}) error
    32  	Render(int, render.Renderer) error
    33  	Error(int, error) error
    34  	Redirect(int, string, ...interface{}) error
    35  	Data() map[string]interface{}
    36  	Flash() *Flash
    37  	File(string) (binding.File, error)
    38  }
    39  
    40  // ParamValues will most commonly be url.Values,
    41  // but isn't it great that you set your own? :)
    42  type ParamValues interface {
    43  	Get(string) string
    44  }
    45  
    46  func (a *App) newContext(info RouteInfo, res http.ResponseWriter, req *http.Request) Context {
    47  	if ws, ok := res.(*Response); ok {
    48  		res = ws
    49  	}
    50  
    51  	// Parse URL Params
    52  	params := url.Values{}
    53  	vars := mux.Vars(req)
    54  	for k, v := range vars {
    55  		params.Add(k, v)
    56  	}
    57  
    58  	// Parse URL Query String Params
    59  	// For POST, PUT, and PATCH requests, it also parse the request body as a form.
    60  	// Request body parameters take precedence over URL query string values in params
    61  	if err := req.ParseForm(); err == nil {
    62  		for k, v := range req.Form {
    63  			for _, vv := range v {
    64  				params.Add(k, vv)
    65  			}
    66  		}
    67  	}
    68  
    69  	session := a.getSession(req, res)
    70  
    71  	ct := httpx.ContentType(req)
    72  
    73  	data := &sync.Map{}
    74  
    75  	data.Store("app", a)
    76  	data.Store("env", a.Env)
    77  	data.Store("routes", a.Routes())
    78  	data.Store("current_route", info)
    79  	data.Store("current_path", req.URL.Path)
    80  	data.Store("contentType", ct)
    81  	data.Store("method", req.Method)
    82  
    83  	for _, route := range a.Routes() {
    84  		cRoute := route
    85  		data.Store(cRoute.PathName, cRoute.BuildPathHelper())
    86  	}
    87  
    88  	return &DefaultContext{
    89  		Context:     req.Context(),
    90  		contentType: ct,
    91  		response:    res,
    92  		request:     req,
    93  		params:      params,
    94  		logger:      a.Logger,
    95  		session:     session,
    96  		flash:       newFlash(session),
    97  		data:        data,
    98  	}
    99  }