func getArticle(w http.ResponseWriter, r *http.Request) { // Load article. if chi.URLParam(r, "articleID") != "1" { render.Respond(w, r, data.ErrNotFound) return } article := &data.Article{ ID: 1, Title: "Article #1", Data: []string{"one", "two", "three", "four"}, CustomDataForAuthUsers: "secret data for auth'd users only", } // Simulate some context values: // 1. ?auth=true simluates authenticated session/user. // 2. ?error=true simulates random error. if r.URL.Query().Get("auth") != "" { r = r.WithContext(context.WithValue(r.Context(), "auth", true)) } if r.URL.Query().Get("error") != "" { render.Respond(w, r, errors.New("error")) return } render.Respond(w, r, article) }
func compilePagePosts(ctx *Context) []*helper.GoWorkerRequest { var reqs []*helper.GoWorkerRequest lists := ctx.Source.PagePosts for page := range lists { pp := lists[page] pageKey := fmt.Sprintf("post-page-%d", pp.Pager.Current) c := context.WithValue(context.Background(), "post-page", pp.Posts) c = context.WithValue(c, "page", pp.Pager) req := &helper.GoWorkerRequest{ Ctx: c, Action: func(c context.Context) (context.Context, error) { viewData := ctx.View() viewData["Title"] = fmt.Sprintf("Page %d - %s", pp.Pager.Current, ctx.Source.Meta.Title) viewData["Posts"] = pp.Posts viewData["Pager"] = pp.Pager viewData["PostType"] = model.TreePostList viewData["PermaKey"] = pageKey viewData["Hover"] = model.TreePostList viewData["URL"] = pp.URL return c, compile(ctx, "posts.html", viewData, pp.DestURL()) }, } reqs = append(reqs, req) } return reqs }
// Pagination adds the values "per_page" and "page" to the context with values // from the query params. func Pagination(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { rawPerPage := chi.URLParam(r, "per_page") rawPage := chi.URLParam(r, "page") if len(rawPerPage) == 0 { rawPerPage = "20" } if len(rawPage) == 0 { rawPage = "0" } var err error var perPage int if perPage, err = strconv.Atoi(rawPerPage); err != nil { perPage = 20 } var page int if page, err = strconv.Atoi(rawPage); err != nil { page = 0 } ctx := r.Context() ctx = context.WithValue(ctx, 1001, perPage) ctx = context.WithValue(ctx, 1002, page) r = r.WithContext(ctx) next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
func compileTagPosts(ctx *Context) []*helper.GoWorkerRequest { var reqs []*helper.GoWorkerRequest lists := ctx.Source.TagPosts for t := range lists { tp := lists[t] c := context.WithValue(context.Background(), "post-tag", tp.Posts) c = context.WithValue(c, "tag", tp.Tag) req := &helper.GoWorkerRequest{ Ctx: c, Action: func(c context.Context) (context.Context, error) { pageURL := path.Join(ctx.Source.Meta.Path, tp.Tag.URL) pageKey := fmt.Sprintf("post-tag-%s", t) viewData := ctx.View() viewData["Title"] = fmt.Sprintf("%s - %s", t, ctx.Source.Meta.Title) viewData["Posts"] = tp.Posts viewData["Tag"] = tp.Tag viewData["PostType"] = model.TreePostTag viewData["PermaKey"] = pageKey viewData["Hover"] = model.TreePostTag viewData["URL"] = pageURL return c, compile(ctx, "posts.html", viewData, tp.DestURL()) }, } reqs = append(reqs, req) } return reqs }
// WithClientTrace returns a new context based on the provided parent // ctx. HTTP client requests made with the returned context will use // the provided trace hooks, in addition to any previous hooks // registered with ctx. Any hooks defined in the provided trace will // be called first. func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context { if trace == nil { panic("nil trace") } old := ContextClientTrace(ctx) trace.compose(old) ctx = context.WithValue(ctx, clientEventContextKey{}, trace) if trace.hasNetHooks() { nt := &nettrace.Trace{ ConnectStart: trace.ConnectStart, ConnectDone: trace.ConnectDone, } if trace.DNSStart != nil { nt.DNSStart = func(name string) { trace.DNSStart(DNSStartInfo{Host: name}) } } if trace.DNSDone != nil { nt.DNSDone = func(netIPs []interface{}, coalesced bool, err error) { addrs := make([]net.IPAddr, len(netIPs)) for i, ip := range netIPs { addrs[i] = ip.(net.IPAddr) } trace.DNSDone(DNSDoneInfo{ Addrs: addrs, Coalesced: coalesced, Err: err, }) } } ctx = context.WithValue(ctx, nettrace.TraceKey{}, nt) } return ctx }
func newCtxWithValues(c *config) context.Context { ctx := context.Background() ctx = context.WithValue(ctx, "googleAPIKey", c.GoogleAPIKey) ctx = context.WithValue(ctx, "googleSearchEngineID", c.GoogleSearchEngineID) ctx = context.WithValue(ctx, "openWeatherMapAppID", c.OpenweathermapAppID) return ctx }
func TestNoMatch(t *testing.T) { t.Parallel() var rt router rt.add(boolPattern(false), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t.Fatal("did not expect handler to be called") })) _, r := wr() ctx := context.Background() ctx = context.WithValue(ctx, internal.Pattern, boolPattern(true)) ctx = context.WithValue(ctx, internal.Pattern, boolPattern(true)) ctx = context.WithValue(ctx, pattern.Variable("answer"), 42) ctx = context.WithValue(ctx, internal.Path, "/") r = r.WithContext(ctx) r = rt.route(r) ctx = r.Context() if p := ctx.Value(internal.Pattern); p != nil { t.Errorf("unexpected pattern %v", p) } if h := ctx.Value(internal.Handler); h != nil { t.Errorf("unexpected handler %v", h) } if h := ctx.Value(pattern.Variable("answer")); h != 42 { t.Errorf("context didn't work: got %v, wanted %v", h, 42) } }
func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) { ctx, cancel = context.WithCancel(context.Background()) ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) if hs := opts.baseConfig(); hs != nil { ctx = context.WithValue(ctx, http.ServerContextKey, hs) } return }
// Handle takes the next handler as an argument and wraps it in this middleware. func (m *Middle) Handle(next httpware.Handler) httpware.Handler { return httpware.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { ctx = context.WithValue(ctx, httpware.RequestContentTypeKey, GetContentMatch(r.Header.Get("Content-Type"))) ct := GetContentMatch(r.Header.Get("Accept")) ctx = context.WithValue(ctx, httpware.ResponseContentTypeKey, ct) w.Header().Set("Content-Type", ct.Value) return next.ServeHTTPCtx(ctx, w, r) }) }
func handle() { key1 := "key1" value1 := "myValue1" ctx := context.WithValue(context.Background(), key1, value1) key2 := "key2" value2 := 2 ctx = context.WithValue(ctx, key2, value2) fmt.Println("Result1:", ctx.Value(key1).(string)) fmt.Println("Result2:", ctx.Value(key2).(int)) }
// ContextWithLoggable returns a derived context which contains the provided // Loggable. Any Events logged with the derived context will include the // provided Loggable. func ContextWithLoggable(ctx context.Context, l Loggable) context.Context { existing, err := MetadataFromContext(ctx) if err != nil { // context does not contain meta. just set the new metadata child := context.WithValue(ctx, metadataKey, Metadata(l.Loggable())) return child } merged := DeepMerge(existing, l.Loggable()) child := context.WithValue(ctx, metadataKey, merged) return child }
func TestExistingContext(t *testing.T) { t.Parallel() pat := New("/hi/:c/:a/:r/:l") req, err := http.NewRequest("GET", "/hi/foo/bar/baz/quux", nil) if err != nil { panic(err) } ctx := context.Background() ctx = pattern.SetPath(ctx, req.URL.EscapedPath()) ctx = context.WithValue(ctx, pattern.AllVariables, map[pattern.Variable]interface{}{ "hello": "world", "c": "nope", }) ctx = context.WithValue(ctx, pattern.Variable("user"), "carl") req = req.WithContext(ctx) req = pat.Match(req) if req == nil { t.Fatalf("expected pattern to match") } ctx = req.Context() expected := map[pattern.Variable]interface{}{ "c": "foo", "a": "bar", "r": "baz", "l": "quux", } for k, v := range expected { if p := Param(req, string(k)); p != v { t.Errorf("expected %s=%q, got %q", k, v, p) } } expected["hello"] = "world" all := ctx.Value(pattern.AllVariables).(map[pattern.Variable]interface{}) if !reflect.DeepEqual(all, expected) { t.Errorf("expected %v, got %v", expected, all) } if path := pattern.Path(ctx); path != "" { t.Errorf("expected path=%q, got %q", "", path) } if user := ctx.Value(pattern.Variable("user")); user != "carl" { t.Errorf("expected user=%q, got %q", "carl", user) } }
// middleware to protect private pages func validate(page http.HandlerFunc) http.HandlerFunc { return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { cookie, err := req.Cookie("Auth") if err != nil { http.NotFound(res, req) return } token, err := jwt.ParseWithClaims(cookie.Value, &Claims{}, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method") } return []byte("secret"), nil }) if err != nil { http.NotFound(res, req) return } if claims, ok := token.Claims.(*Claims); ok && token.Valid { ctx := context.WithValue(req.Context(), MyKey, *claims) page(res, req.WithContext(ctx)) } else { http.NotFound(res, req) return } }) }
func NewSearchFlag(ctx context.Context, t int) (*SearchFlag, context.Context) { if v := ctx.Value(searchFlagKey); v != nil { return v.(*SearchFlag), ctx } v := &SearchFlag{ t: t, } v.ClientFlag, ctx = NewClientFlag(ctx) v.DatacenterFlag, ctx = NewDatacenterFlag(ctx) switch t { case SearchVirtualMachines: v.entity = "VM" case SearchHosts: v.entity = "host" case SearchVirtualApps: v.entity = "vapp" default: panic("invalid search type") } ctx = context.WithValue(ctx, searchFlagKey, v) return v, ctx }
func Set(r *http.Request, key, val interface{}) *http.Request { if val == nil { return r } return r.WithContext(context.WithValue(r.Context(), key, val)) }
func main() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. ctx, cancel := context.WithTimeout(context.Background(), 3000*time.Millisecond) ctx = context.WithValue(ctx, "a", 42) go t(ctx) // time.Sleep(time.Millisecond * 200) // cancel() select { case <-time.After(4 * time.Second): fmt.Println("overslept") case <-ctx.Done(): fmt.Println(ctx.Err()) // prints "context deadline exceeded" } // Even though ctx should have expired already, it is good // practice to call its cancelation function in any case. // Failure to do so may keep the context and its parent alive // longer than necessary. fmt.Println(ctx.Value("a")) cancel() }
// scrapeRoute parses and responds to a Scrape by using t.TrackerLogic. func (t *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var err error start := time.Now() defer recordResponseDuration("scrape", err, time.Since(start)) req, err := ParseScrape(r) if err != nil { WriteError(w, err) return } host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { log.Errorln("http: unable to determine remote address for scrape:", err) WriteError(w, err) return } ip := net.ParseIP(host) ctx := context.WithValue(context.Background(), middleware.ScrapeIsIPv6Key, len(ip) == net.IPv6len) resp, err := t.logic.HandleScrape(ctx, req) if err != nil { WriteError(w, err) return } err = WriteScrapeResponse(w, resp) if err != nil { WriteError(w, err) return } go t.logic.AfterScrape(context.Background(), req, resp) }
func TestHasAll(t *testing.T) { body := "test=true&keys=this,that,something&values=1,2,3" r, err := http.NewRequest("PUT", "test", strings.NewReader(body)) if err != nil { t.Fatal("Could not build request", err) } r.Header.Set("Content-Type", "application/x-www-form-urlencoded") r = r.WithContext(context.WithValue(r.Context(), paramsKey, ParseParams(r))) params := GetParams(r) //Test All if ok, missing := params.HasAll("test", "keys", "values"); !ok || len(missing) > 0 { t.Fatal("Params should have all keys, could not find", missing) } // Test Partial Contains if ok, missing := params.HasAll("test"); !ok || len(missing) > 0 { t.Fatal("Params should have key 'test', could not find", missing) } // Test Partial Missing if ok, missing := params.HasAll("test", "nope"); ok || len(missing) == 0 { t.Fatal("Params should not have key 'nope'", missing) } else if contains(missing, "test") { t.Fatal("Missing should not contain 'test'") } // Test All missing if ok, missing := params.HasAll("negative", "nope"); ok || len(missing) == 0 { t.Fatal("Params should not have key 'nope' nor 'negative'", missing) } }
func TestImbueTime(t *testing.T) { body := "test=true&created_at=2016-06-07T00:30Z&remind_on=2016-07-17" r, err := http.NewRequest("PUT", "test", strings.NewReader(body)) if err != nil { t.Fatal("Could not build request", err) } r.Header.Set("Content-Type", "application/x-www-form-urlencoded") r = r.WithContext(context.WithValue(r.Context(), paramsKey, ParseParams(r))) params := GetParams(r) type testType struct { Test bool CreatedAt time.Time RemindOn *time.Time } var obj testType params.Imbue(&obj) if obj.Test != true { t.Fatal("Value of 'test' should be 'true', got: ", obj.Test) } createdAt, _ := time.Parse(time.RFC3339, "2016-06-07T00:30Z00:00") if !obj.CreatedAt.Equal(createdAt) { t.Fatal("CreatedAt should be '2016-06-07T00:30Z', got:", obj.CreatedAt) } remindOn, _ := time.Parse(DateOnly, "2016-07-17") if obj.RemindOn == nil || !obj.RemindOn.Equal(remindOn) { t.Fatal("RemindOn should be '2016-07-17', got:", obj.RemindOn) } }
func TestParsePostUrlJSON(t *testing.T) { body := "{\"test\":true}" r, err := http.NewRequest("PUT", "test?test=false&id=1", strings.NewReader(body)) if err != nil { t.Fatal("Could not build request", err) } r.Header.Set("Content-Type", "application/json") r = r.WithContext(context.WithValue(r.Context(), paramsKey, ParseParams(r))) params := GetParams(r) val, present := params.Get("test") if !present { t.Fatal("Key: 'test' not found") } if val != true { t.Fatal("Value of 'test' should be 'true', got: ", val) } val, present = params.GetFloatOk("id") if !present { t.Fatal("Key: 'id' not found") } if val != 1.0 { t.Fatal("Value of 'id' should be 1, got: ", val) } }
func TestRouter(t *testing.T) { t.Parallel() var rt router mark := new(int) for i, p := range TestRoutes { i := i p.index = i p.mark = mark rt.add(p, intHandler(i)) } for i, test := range RouterTests { r, err := http.NewRequest(test.method, test.path, nil) if err != nil { panic(err) } ctx := context.WithValue(context.Background(), internal.Path, test.path) r = r.WithContext(ctx) var out []int for *mark = 0; *mark < len(TestRoutes); *mark++ { r := rt.route(r) ctx := r.Context() if h := ctx.Value(internal.Handler); h != nil { out = append(out, int(h.(intHandler))) } else { out = append(out, -1) } } if !reflect.DeepEqual(out, test.results) { t.Errorf("[%d] expected %v got %v", i, test.results, out) } } }
func TestRoutingVariableWithContext(t *testing.T) { var ( expected = "variable" got string mux = New() w = httptest.NewRecorder() ) appFn := func(w http.ResponseWriter, r *http.Request) { got = GetValue(r, "vartest") } middlewareFn := func(w http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), "key", "customValue") newReq := r.WithContext(ctx) appFn(w, newReq) } mux.Get("/:vartest", http.HandlerFunc(middlewareFn)) r, err := http.NewRequest("GET", fmt.Sprintf("/%s", expected), nil) if err != nil { t.Fatal(err) } mux.ServeHTTP(w, r) if got != expected { t.Fatalf("expected %s, got %s", expected, got) } }
// Handle takes the next handler as an argument and wraps it in this middleware. func (m *Middle) Handle(next httpware.Handler) httpware.Handler { return httpware.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { q := r.URL.Query() s := q.Get(m.startQuery) l := q.Get(m.limitQuery) page := Page{} var err error if s == "" { page.Start = 0 } else { page.Start, err = strconv.Atoi(s) if err != nil { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.startQuery, "must be an integer") } if page.Start < 0 { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.startQuery, "must not be negative") } } if l == "" { page.Limit = m.limitDefault } else { page.Limit, err = strconv.Atoi(l) if err != nil { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.limitQuery, "must not be an integer") } if page.Limit <= 0 { return httpware.NewErr("invalid query parameter", http.StatusBadRequest).WithField(m.limitQuery, "must not be greater than zero") } } return next.ServeHTTPCtx(context.WithValue(ctx, httpware.PageKey, page), w, r) }) }
func compilePosts(ctx *Context) []*helper.GoWorkerRequest { posts := ctx.Source.Posts if len(posts) == 0 { log15.Warn("NoPosts") return nil } var reqs []*helper.GoWorkerRequest for _, post := range posts { p2 := post c := context.WithValue(context.Background(), "post", p2) req := &helper.GoWorkerRequest{ Ctx: c, Action: func(c context.Context) (context.Context, error) { viewData := ctx.View() viewData["Title"] = p2.Title + " - " + ctx.Source.Meta.Title viewData["Desc"] = p2.Desc viewData["Post"] = p2 viewData["PermaKey"] = p2.Slug viewData["PostType"] = model.TreePost viewData["Hover"] = model.TreePost viewData["URL"] = p2.URL() return c, compile(ctx, "post.html", viewData, p2.DestURL()) }, } reqs = append(reqs, req) } return reqs }
func ExampleStack() { // Associate a session ID with each session var sessionID int64 sessionid := styx.HandlerFunc(func(s *styx.Session) { id := atomic.AddInt64(&sessionID, 1) for s.Next() { req := s.Request() ctx := context.WithValue(req.Context(), "session", id) s.UpdateRequest(req.WithContext(ctx)) } }) // echo requests to stdout echo := styx.HandlerFunc(func(s *styx.Session) { for s.Next() { req := s.Request() id := req.Context().Value("session") fmt.Printf("session %v user %q %q %T %s", id, s.User, s.Access, req, req.Path()) } }) // Disallow removal of any files blockops := styx.HandlerFunc(func(s *styx.Session) { for s.Next() { if t, ok := s.Request().(styx.Tremove); ok { t.Rerror("permission denied") } } }) handler := styx.Stack(sessionid, echo, blockops) styx.ListenAndServe(":564", handler) }
func (k *Kloud) doPlan(r *kite.Request, p Provider, teamReq *TeamRequest, req *PlanRequest) ([]*Machine, error) { kiteReq := &kite.Request{ Method: "plan", Username: r.Username, } stack, ctx, err := k.newStack(kiteReq, teamReq) if err != nil { return nil, err } ctx = context.WithValue(ctx, PlanRequestKey, req) v, err := stack.HandlePlan(ctx) if err != nil { return nil, err } k.Log.Debug("plan received: %# v", v) var machines []*Machine if v, ok := v.(*PlanResponse); ok { if m, ok := v.Machines.([]*Machine); ok { machines = m } } return machines, nil }
func TestContextValueChange(t *testing.T) { testConf, err := filepath.Abs("./test/workflow.yaml") if err != nil { t.Fatal(err) } okFn := func(ctx context.Context) (context.Context, string, error) { ctx = context.WithValue(ctx, "key", "value") return ctx, "OK", nil } wf := New() NewAgent(wf.Context, okFn, "start", "step1", "step2", "step3", "step4") err = wf.Load(testConf) if err != nil { t.Log(testConf) t.Error(err) } err = wf.Handle("start") if err != nil { t.Error(err) } value, ok := wf.Context.Value("key").(string) t.Log(value, ok) if !ok { t.Error("value is not string") } if value != "value" { t.Error("value is not value", value) } }
// ServerBaseContext wraps an http.Handler to set the request context to the // `baseCtx`. func ServerBaseContext(h http.Handler, baseCtx context.Context) http.Handler { fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() // Copy over default net/http server context keys if v, ok := ctx.Value(http.ServerContextKey).(*http.Server); ok { baseCtx = context.WithValue(baseCtx, http.ServerContextKey, v) } if v, ok := ctx.Value(http.LocalAddrContextKey).(net.Addr); ok { baseCtx = context.WithValue(baseCtx, http.LocalAddrContextKey, v) } h.ServeHTTP(w, r.WithContext(baseCtx)) }) return fn }
// AdaptFunc can be the starting point for httpware.Handler implementations. It // creates a new background context and invokes the ServeHTTPCtx function. func AdaptFunc(hf httpware.HandlerFunc) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { ctx := context.Background() paramsCtx := context.WithValue(ctx, httpware.RouterParamsKey, ps) hf.ServeHTTPCtx(paramsCtx, w, r) } }
func TestParseNestedJSONBody(t *testing.T) { body := "{ \"test\": true, \"coord\": { \"lat\": 50.505, \"lon\": 10.101 }}" r, err := http.NewRequest("POST", "test", strings.NewReader(body)) if err != nil { t.Fatal("Could not build request", err) } r.Header.Set("Content-Type", "application/json") r = r.WithContext(context.WithValue(r.Context(), paramsKey, ParseParams(r))) params := GetParams(r) val, present := params.Get("test") if !present { t.Fatal("Key: 'test' not found") } if val != true { t.Fatal("Value of 'test' should be 'true', got: ", val) } val, present = params.Get("coord") if !present { t.Fatal("Key: 'coord' not found") } coord := val.(map[string]interface{}) lat, present := coord["lat"] if !present { t.Fatal("Key: 'lat' not found") } if lat != 50.505 { t.Fatal("Value of 'lat' should be 50.505, got: ", lat) } lat, present = params.Get("coord.lat") if !present { t.Fatal("Nested Key: 'lat' not found") } if lat != 50.505 { t.Fatal("Value of 'lat' should be 50.505, got: ", lat) } lon, present := coord["lon"] if !present { t.Fatal("Key: 'lon' not found") } if lon != 10.101 { t.Fatal("Value of 'lon' should be 10.101, got: ", lon) } lon, present = params.Get("coord.lon") if !present { t.Fatal("Nested Key: 'lon' not found") } if lon != 10.101 { t.Fatal("Value of 'lon' should be 10.101, got: ", lon) } }