good morning!!!!

Skip to content
Snippets Groups Projects
Select Git revision
  • 74df5b75f89ebba019d55adfc3e0b491f0b32323
  • master default protected
  • add-tests
  • extensions
  • gateway
  • codec-bundle
  • renovate/github.com-gfx-labs-sse-digest
  • renovate/golang.org-x-net-0.x
  • renovate/golang-1.x
  • jsonv2
  • garet
  • check
  • http-curse
  • whatthefuck
  • pool
  • envelope
  • mod
  • simplify
  • new-interface
  • v2
  • master-old
  • v0.8.0
  • v0.7.0
  • v0.6.1
  • v0.6.0
  • v0.5.4
  • v0.5.3
  • v0.5.2
  • v0.5.1
  • v0.5.0
  • v0.4.19
  • v0.4.18
  • v0.4.17
  • v0.4.16
  • v0.4.15
  • v0.4.14
  • v0.4.13
  • v0.4.12
  • v0.4.11
  • v0.4.10
  • v0.4.9
41 results

context.go

Blame
  • a's avatar
    a authored
    5e0f78df
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    context.go 4.67 KiB
    package jrpc
    
    import (
    	"context"
    	"net/http"
    	"strings"
    )
    
    // MethodParam returns the url parameter from a http.Request object.
    func MethodParam(r *http.Request, key string) string {
    	if rctx := RouteContext(r.Context()); rctx != nil {
    		return rctx.MethodParam(key)
    	}
    	return ""
    }
    
    // MethodParamFromCtx returns the url parameter from a http.Request Context.
    func MethodParamFromCtx(ctx context.Context, key string) string {
    	if rctx := RouteContext(ctx); rctx != nil {
    		return rctx.MethodParam(key)
    	}
    	return ""
    }
    
    // RouteContext returns chi's routing Context object from a
    // http.Request Context.
    func RouteContext(ctx context.Context) *Context {
    	val, _ := ctx.Value(RouteCtxKey).(*Context)
    	return val
    }
    
    // NewRouteContext returns a new routing Context object.
    func NewRouteContext() *Context {
    	return &Context{}
    }
    
    var (
    	// RouteCtxKey is the context.Context key to store the request context.
    	RouteCtxKey = &contextKey{"RouteContext"}
    )
    
    // Context is the default routing context set on the root node of a
    // request context to track route patterns, Method parameters and
    // an optional routing path.
    type Context struct {
    	Routes Routes
    
    	// parentCtx is the parent of this one, for using Context as a
    	// context.Context directly. This is an optimization that saves
    	// 1 allocation.
    	parentCtx context.Context
    
    	// Routing path/method override used during the route search.
    	// See Mux#routeHTTP method.
    	RoutePath   string
    	RouteMethod string
    
    	// MethodParams are the stack of routeParams captured during the
    	// routing lifecycle across a stack of sub-routers.
    	MethodParams RouteParams
    
    	// Route parameters matched for the current sub-router. It is
    	// intentionally unexported so it cant be tampered.
    	routeParams RouteParams
    
    	// The endpoint routing pattern that matched the request URI path
    	// or `RoutePath` of the current sub-router. This value will update
    	// during the lifecycle of a request passing through a stack of
    	// sub-routers.
    	routePattern string
    
    	// Routing pattern stack throughout the lifecycle of the request,
    	// across all connected routers. It is a record of all matching
    	// patterns across a stack of sub-routers.
    	RoutePatterns []string
    
    	// methodNotAllowed hint
    	methodNotAllowed bool
    }
    
    // Reset a routing context to its initial state.
    func (x *Context) Reset() {
    	x.Routes = nil
    	x.RoutePath = ""
    	x.RouteMethod = ""
    	x.RoutePatterns = x.RoutePatterns[:0]
    	x.MethodParams.Keys = x.MethodParams.Keys[:0]
    	x.MethodParams.Values = x.MethodParams.Values[:0]
    
    	x.routePattern = ""
    	x.routeParams.Keys = x.routeParams.Keys[:0]
    	x.routeParams.Values = x.routeParams.Values[:0]
    	x.methodNotAllowed = false
    	x.parentCtx = nil
    }
    
    // MethodParam returns the corresponding Method parameter value from the request
    // routing context.
    func (x *Context) MethodParam(key string) string {
    	for k := len(x.MethodParams.Keys) - 1; k >= 0; k-- {
    		if x.MethodParams.Keys[k] == key {
    			return x.MethodParams.Values[k]
    		}
    	}
    	return ""
    }
    
    // RoutePattern builds the routing pattern string for the particular
    // request, at the particular point during routing. This means, the value
    // will change throughout the execution of a request in a router. That is
    // why its advised to only use this value after calling the next handler.
    //
    // For example,
    //
    //   func Instrument(next http.Handler) http.Handler {
    //     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    //       next.ServeHTTP(w, r)
    //       routePattern := chi.RouteContext(r.Context()).RoutePattern()
    //       measure(w, r, routePattern)
    //   	 })
    //   }
    func (x *Context) RoutePattern() string {
    	routePattern := strings.Join(x.RoutePatterns, "")
    	routePattern = replaceWildcards(routePattern)
    	routePattern = strings.TrimSuffix(routePattern, "//")
    	routePattern = strings.TrimSuffix(routePattern, "/")
    	return routePattern
    }
    
    // replaceWildcards takes a route pattern and recursively replaces all
    // occurrences of "/*/" to "/".
    func replaceWildcards(p string) string {
    	if strings.Contains(p, "/*/") {
    		return replaceWildcards(strings.Replace(p, "/*/", "/", -1))
    	}
    	return p
    }
    
    // RouteParams is a structure to track Method routing parameters efficiently.
    type RouteParams struct {
    	Keys, Values []string
    }
    
    // Add will append a Method parameter to the end of the route param
    func (s *RouteParams) Add(key, value string) {
    	s.Keys = append(s.Keys, key)
    	s.Values = append(s.Values, value)
    }
    
    // contextKey is a value for use with context.WithValue. It's used as
    // a pointer so it fits in an interface{} without allocation. This technique
    // for defining context keys was copied from Go 1.7's new use of context in net/http.
    type contextKey struct {
    	name string
    }
    
    func (k *contextKey) String() string {
    	return "jsonrpc2 context value " + k.name
    }