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 }