Пример #1
2
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)
}
Пример #2
0
func Set(r *http.Request, key, val interface{}) *http.Request {
	if val == nil {
		return r
	}

	return r.WithContext(context.WithValue(r.Context(), key, val))
}
Пример #3
0
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})
}
Пример #4
0
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))
}
Пример #5
0
func doRequestWithClient(
	ctx types.Context,
	client *http.Client,
	req *http.Request) (*http.Response, error) {
	req = req.WithContext(ctx)
	return client.Do(req)
}
Пример #6
0
func (t *TreeMux) setDefaultRequestContext(r *http.Request) *http.Request {
	if t.DefaultContext != nil {
		r = r.WithContext(t.DefaultContext)
	}

	return r
}
Пример #7
0
func setContext(r *http.Request, key, val interface{}) {
	if val == nil {
		return
	}

	r2 := r.WithContext(context.WithValue(r.Context(), key, val))
	*r = *r2
}
Пример #8
0
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
}
Пример #9
0
Файл: mux.go Проект: goji/goji
// 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)
}
Пример #10
0
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()})
}
Пример #11
0
// 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
}
Пример #12
0
Файл: web.go Проект: daaku/rell
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
}
Пример #13
0
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
}
Пример #14
0
// 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
}
Пример #15
0
// 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))
}
Пример #16
0
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
		}(), ", "))
	}
}
Пример #17
0
Файл: mux.go Проект: pressly/chi
// 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)
}
Пример #18
0
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
}
Пример #19
0
// 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)
}
Пример #20
0
func WithLogEntry(r *http.Request, entry LogEntry) *http.Request {
	r = r.WithContext(context.WithValue(r.Context(), LogEntryCtxKey, entry))
	return r
}
Пример #21
0
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)
			}
		}
	}
}
Пример #22
0
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()
}
Пример #23
0
// 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)
}
Пример #24
0
func addNosurfContext(r *http.Request) *http.Request {
	return r.WithContext(context.WithValue(r.Context(), nosurfKey, &csrfContext{}))
}
Пример #25
0
func withContext(r *http.Request, ctx context.Context) *http.Request {
	return r.WithContext(ctx)
}
Пример #26
0
func contextSave(r *http.Request, key string, val interface{}) *http.Request {
	ctx := r.Context()
	ctx = context.WithValue(ctx, key, val)
	return r.WithContext(ctx)
}
Пример #27
0
// 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))
}
Пример #28
0
func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
	return req.WithContext(ctx)
}
Пример #29
0
// 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)
}
Пример #30
0
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)
}