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 Set(r *http.Request, key, val interface{}) *http.Request { if val == nil { return r } return r.WithContext(context.WithValue(r.Context(), key, val)) }
func (rt *router) route(r *http.Request) *http.Request { tn := &rt.wildcard if tn2, ok := rt.methods[r.Method]; ok { tn = tn2 } ctx := r.Context() path := ctx.Value(internal.Path).(string) for path != "" { i := sort.Search(len(tn.children), func(i int) bool { return path[0] <= tn.children[i].prefix[0] }) if i == len(tn.children) || !strings.HasPrefix(path, tn.children[i].prefix) { break } path = path[len(tn.children[i].prefix):] tn = tn.children[i].node } for _, i := range tn.routes { if r2 := rt.routes[i].Match(r); r2 != nil { return r2.WithContext(&match{ Context: r2.Context(), p: rt.routes[i].Pattern, h: rt.routes[i].Handler, }) } } return r.WithContext(&match{Context: ctx}) }
func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) { if nil == ctx || nil == ctx.Done() { // ctx.Done() is for ctx return c.Client.Do(req) } return c.Client.Do(req.WithContext(ctx)) }
func doRequestWithClient( ctx types.Context, client *http.Client, req *http.Request) (*http.Response, error) { req = req.WithContext(ctx) return client.Do(req) }
func (t *TreeMux) setDefaultRequestContext(r *http.Request) *http.Request { if t.DefaultContext != nil { r = r.WithContext(t.DefaultContext) } return r }
func setContext(r *http.Request, key, val interface{}) { if val == nil { return } r2 := r.WithContext(context.WithValue(r.Context(), key, val)) *r = *r2 }
func newRun(w http.ResponseWriter, r *http.Request, handler []http.Handler) *Run { run := &Run{ rWriter: w, handler: handler, } run.request = r.WithContext(context.WithValue(r.Context(), ctxRun, run)) return run }
// ServeHTTP implements net/http.Handler. func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { if m.root { ctx := r.Context() ctx = context.WithValue(ctx, internal.Path, r.URL.EscapedPath()) r = r.WithContext(ctx) } r = m.router.route(r) m.handler.ServeHTTP(w, r) }
func (rt *router) route(r *http.Request) *http.Request { for _, route := range *rt { if r2 := route.Match(r); r2 != nil { return r2.WithContext(&match{ Context: r2.Context(), p: route.Pattern, h: route.Handler, }) } } return r.WithContext(&match{Context: r.Context()}) }
// ensureComponentsInitialize checks if the appliance components are initialized by issuing // `docker info` to the appliance func (d *Dispatcher) ensureComponentsInitialize(conf *config.VirtualContainerHostConfigSpec) error { var ( proto string client *http.Client res *http.Response err error req *http.Request ) if conf.HostCertificate.IsNil() { // TLS disabled proto = "http" client = &http.Client{} } else { // TLS enabled proto = "https" // TODO: configure this when support is added for user-signed certs tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client = &http.Client{Transport: tr} } dockerInfoURL := fmt.Sprintf("%s://%s:%s/info", proto, d.HostIP, d.DockerPort) req, err = http.NewRequest("GET", dockerInfoURL, nil) if err != nil { return errors.New("invalid HTTP request for docker info") } req = req.WithContext(d.ctx) ticker := time.NewTicker(time.Second) defer ticker.Stop() for { res, err = client.Do(req) if err == nil && res.StatusCode == http.StatusOK { if isPortLayerRunning(res) { break } } select { case <-ticker.C: case <-d.ctx.Done(): return d.ctx.Err() } log.Debug("Components not initialized yet, retrying docker info request") } return nil }
func (a *Handler) contextChanger(r *http.Request) (*http.Request, error) { env, err := a.EnvParser.FromRequest(r) if err != nil { return nil, err } ctx := r.Context() ctx = ctxerr.WithConfig(ctx, ctxerr.Config{ StackMode: ctxerr.StackModeMultiStack, StringMode: ctxerr.StringModeNone, }) ctx = rellenv.WithEnv(ctx, env) ctx = static.NewContext(ctx, a.Static) return r.WithContext(ctx), nil }
func NewContextForRequest(w ResponseWriter, r *http.Request, cur_route *Route) context.Context { vars := cur_route.RouteVars(r) if vars == nil { vars = make(map[string]string) } req_ctx := &RequestContext{ writer: w, currentRoute: cur_route, routeVars: vars, } ctx := context.WithValue(r.Context(), requestContextCtxKey, req_ctx) req_ctx.request = r.WithContext(ctx) return ctx }
// Do sends an HTTP request with the provided http.Client and returns // an HTTP response. // // If the client is nil, http.DefaultClient is used. // // The provided ctx must be non-nil. If it is canceled or times out, // ctx.Err() will be returned. func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { if client == nil { client = http.DefaultClient } resp, err := client.Do(req.WithContext(ctx)) // If we got an error, and the context has been canceled, // the context's error is probably more useful. if err != nil { select { case <-ctx.Done(): err = ctx.Err() default: } } return resp, err }
// logDataAdd adds a single value to the log context func logDataAdd(r *http.Request, key string, value interface{}) { var data map[string]interface{} ctx := r.Context() d := ctx.Value("log") switch v := d.(type) { case map[string]interface{}: data = v default: data = make(map[string]interface{}) } data[key] = value r = r.WithContext(context.WithValue(ctx, "log", data)) }
func (me *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { matches := me.matchingHandlers(r) switch len(matches) { case 0: http.NotFound(w, r) return case 1: m := matches[0] r = r.WithContext(context.WithValue(r.Context(), pathParamContextKey, &PathParams{m})) m.handler.userHandler.ServeHTTP(w, r) default: panic("multiple handlers match: " + strings.Join(func() (ret []string) { for _, m := range matches { ret = append(ret, m.handler.path.String()) } return }(), ", ")) } }
// ServeHTTP is the single method of the http.Handler interface that makes // Mux interoperable with the standard library. It uses a sync.Pool to get and // reuse routing contexts for each request. func (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Ensure the mux has some routes defined on the mux if mx.handler == nil { panic("chi: attempting to route to a mux with no handlers.") } // Check if a routing context already exists from a parent router. rctx, _ := r.Context().Value(RouteCtxKey).(*Context) if rctx != nil { mx.handler.ServeHTTP(w, r) return } // Fetch a RouteContext object from the sync pool, and call the computed // mx.handler that is comprised of mx.middlewares + mx.routeHTTP. // Once the request is finished, reset the routing context and put it back // into the pool for reuse from another request. rctx = mx.pool.Get().(*Context) rctx.reset() r = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx)) mx.handler.ServeHTTP(w, r) mx.pool.Put(rctx) }
func execPing( client *http.Client, req *http.Request, body []byte, timeout time.Duration, validator func(*http.Response) error, ) (common.MapStr, reason.Reason) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() req = req.WithContext(ctx) if len(body) > 0 { req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) req.ContentLength = int64(len(body)) } start := time.Now() resp, err := client.Do(req) end := time.Now() if err != nil { return nil, reason.IOFailed(err) } defer resp.Body.Close() if err := validator(resp); err != nil { return nil, reason.ValidateFailed(err) } rtt := end.Sub(start) event := common.MapStr{ "response": common.MapStr{ "status": resp.StatusCode, }, "rtt": look.RTT(rtt), } return event, nil }
// Decode the JSON request and verify it. func verifyJSON(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { var echoReq *EchoRequest err := json.NewDecoder(r.Body).Decode(&echoReq) if err != nil { HTTPError(w, err.Error(), "Bad Request", 400) return } // Check the timestamp if !echoReq.VerifyTimestamp() && r.URL.Query().Get("_dev") == "" { HTTPError(w, "Request too old to continue (>150s).", "Bad Request", 400) return } // Check the app id if !echoReq.VerifyAppID(Applications[r.URL.Path].(EchoApplication).AppID) { HTTPError(w, "Echo AppID mismatch!", "Bad Request", 400) return } r = r.WithContext(context.WithValue(r.Context(), "echoRequest", echoReq)) next(w, r) }
func WithLogEntry(r *http.Request, entry LogEntry) *http.Request { r = r.WithContext(context.WithValue(r.Context(), LogEntryCtxKey, entry)) return r }
func (h Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { var err error remoteAddr := req.RemoteAddr // Prepare filter.Context ctx := filters.NewContext(req.Context(), h, h.Listener, rw, h.Branding) req = req.WithContext(ctx) // Enable transport http proxy if req.Method != "CONNECT" && !req.URL.IsAbs() { if req.URL.Scheme == "" { if req.TLS != nil && req.ProtoMajor == 1 { req.URL.Scheme = "https" } else { req.URL.Scheme = "http" } } if req.TLS != nil { if req.Host == "" { if req.URL.Host != "" { req.Host = req.URL.Host } else { req.Host = req.TLS.ServerName } } if req.URL.Host == "" { if req.Host != "" { req.URL.Host = req.Host } else { req.URL.Host = req.TLS.ServerName } } } } // Filter Request for _, f := range h.RequestFilters { ctx, req, err = f.Request(ctx, req) if req == filters.DummyRequest { return } if err != nil { if err != io.EOF { glog.Errorf("%s Filter Request %T error: %+v", remoteAddr, f, err) } return } // Update context for request req = req.WithContext(ctx) } if req.Body != nil { defer req.Body.Close() } // Filter Request -> Response var resp *http.Response for _, f := range h.RoundTripFilters { ctx, resp, err = f.RoundTrip(ctx, req) if resp == filters.DummyResponse { return } // Unexcepted errors if err != nil { filters.SetRoundTripFilter(ctx, f) glog.Errorf("%s Filter RoundTrip %T error: %+v", remoteAddr, f, err) http.Error(rw, h.FormatError(ctx, err), http.StatusBadGateway) return } // Update context for request req = req.WithContext(ctx) // A roundtrip filter give a response if resp != nil { resp.Request = req filters.SetRoundTripFilter(ctx, f) break } } // Filter Response for _, f := range h.ResponseFilters { if resp == nil || resp == filters.DummyResponse { return } ctx, resp, err = f.Response(ctx, resp) if err != nil { glog.Errorln("%s Filter %T Response error: %+v", remoteAddr, f, err) http.Error(rw, h.FormatError(ctx, err), http.StatusBadGateway) return } // Update context for request req = req.WithContext(ctx) } if resp == nil { glog.Errorln("%s Handler %#v Response empty response", remoteAddr, h) http.Error(rw, h.FormatError(ctx, fmt.Errorf("empty response")), http.StatusBadGateway) return } if resp.Header.Get("Content-Length") == "" && resp.ContentLength >= 0 { resp.Header.Set("Content-Length", strconv.FormatInt(resp.ContentLength, 10)) } for key, values := range resp.Header { for _, value := range values { rw.Header().Add(key, value) } } rw.WriteHeader(resp.StatusCode) if resp.Body != nil { defer resp.Body.Close() n, err := helpers.IOCopy(rw, resp.Body) if err != nil { if isClosedConnError(err) { glog.Infof("IOCopy %#v return %#v %T(%v)", resp.Body, n, err, err) } else { glog.Warningf("IOCopy %#v return %#v %T(%v)", resp.Body, n, err, err) } } } }
func (h ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { p := NewProfile(w, r, FuncName(h.f)) ctx := context.WithValue(r.Context(), contextKey, p) h.f(w, r.WithContext(ctx)) p.Finalize() }
// SetUser stores a user in the request context. func SetUser(r *http.Request, user *entities.User) *http.Request { ctx := context.WithValue(r.Context(), userKey, user) return r.WithContext(ctx) }
func addNosurfContext(r *http.Request) *http.Request { return r.WithContext(context.WithValue(r.Context(), nosurfKey, &csrfContext{})) }
func withContext(r *http.Request, ctx context.Context) *http.Request { return r.WithContext(ctx) }
func contextSave(r *http.Request, key string, val interface{}) *http.Request { ctx := r.Context() ctx = context.WithValue(ctx, key, val) return r.WithContext(ctx) }
// logDataReplace replaces the current log context with the provided log data func logDataReplace(r *http.Request, data map[string]interface{}) { ctx := r.Context() r = r.WithContext(context.WithValue(ctx, "log", data)) }
func requestWithContext(req *http.Request, ctx contextContext) *http.Request { return req.WithContext(ctx) }
// SetLog stores a log entry in the request context. func SetLog(r *http.Request, log *logrus.Entry) *http.Request { ctx := context.WithValue(r.Context(), logKey, log) return r.WithContext(ctx) }
func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { transport := p.Transport if transport == nil { transport = http.DefaultTransport } ctx := req.Context() if cn, ok := rw.(http.CloseNotifier); ok { var cancel context.CancelFunc ctx, cancel = context.WithCancel(ctx) defer cancel() notifyChan := cn.CloseNotify() go func() { select { case <-notifyChan: cancel() case <-ctx.Done(): } }() } outreq := new(http.Request) *outreq = *req // includes shallow copies of maps, but okay if req.ContentLength == 0 { outreq.Body = nil // Issue 16036: nil Body for http.Transport retries } outreq = outreq.WithContext(ctx) p.Director(outreq) outreq.Close = false // We are modifying the same underlying map from req (shallow // copied above) so we only copy it if necessary. copiedHeaders := false // Remove hop-by-hop headers listed in the "Connection" header. // See RFC 2616, section 14.10. if c := outreq.Header.Get("Connection"); c != "" { for _, f := range strings.Split(c, ",") { if f = strings.TrimSpace(f); f != "" { if !copiedHeaders { outreq.Header = make(http.Header) copyHeader(outreq.Header, req.Header) copiedHeaders = true } outreq.Header.Del(f) } } } // Remove hop-by-hop headers to the backend. Especially // important is "Connection" because we want a persistent // connection, regardless of what the client sent to us. for _, h := range hopHeaders { if outreq.Header.Get(h) != "" { if !copiedHeaders { outreq.Header = make(http.Header) copyHeader(outreq.Header, req.Header) copiedHeaders = true } outreq.Header.Del(h) } } if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { // If we aren't the first proxy retain prior // X-Forwarded-For information as a comma+space // separated list and fold multiple headers into one. if prior, ok := outreq.Header["X-Forwarded-For"]; ok { clientIP = strings.Join(prior, ", ") + ", " + clientIP } outreq.Header.Set("X-Forwarded-For", clientIP) } res, err := transport.RoundTrip(outreq) if err != nil { p.logf("http: proxy error: %v", err) rw.WriteHeader(http.StatusBadGateway) return } // Remove hop-by-hop headers listed in the // "Connection" header of the response. if c := res.Header.Get("Connection"); c != "" { for _, f := range strings.Split(c, ",") { if f = strings.TrimSpace(f); f != "" { res.Header.Del(f) } } } for _, h := range hopHeaders { res.Header.Del(h) } copyHeader(rw.Header(), res.Header) // The "Trailer" header isn't included in the Transport's response, // at least for *http.Transport. Build it up from Trailer. if len(res.Trailer) > 0 { trailerKeys := make([]string, 0, len(res.Trailer)) for k := range res.Trailer { trailerKeys = append(trailerKeys, k) } rw.Header().Add("Trailer", strings.Join(trailerKeys, ", ")) } rw.WriteHeader(res.StatusCode) if len(res.Trailer) > 0 { // Force chunking if we saw a response trailer. // This prevents net/http from calculating the length for short // bodies and adding a Content-Length. if fl, ok := rw.(http.Flusher); ok { fl.Flush() } } p.copyResponse(rw, res.Body) res.Body.Close() // close now, instead of defer, to populate res.Trailer copyHeader(rw.Header(), res.Trailer) }