MCPcopy
hub / github.com/labstack/echo / Route

Method Route

router.go:788–1039  ·  view source on GitHub ↗

Route looks up a handler registered for method and path. It also parses URL for path parameters and loads them into context. For performance: - Get context from `Echo#AcquireContext()` - Reset it `Context#Reset()` - Return it `Echo#ReleaseContext()`.

(c *Context)

Source from the content-addressed store, hash-verified

786// - Reset it `Context#Reset()`
787// - Return it `Echo#ReleaseContext()`.
788func (r *DefaultRouter) Route(c *Context) HandlerFunc {
789 pathValues := c.PathValues()
790 if cap(pathValues) < r.maxPathParamsLength {
791 pathValues = make(PathValues, 0, r.maxPathParamsLength)
792 } else {
793 pathValues = pathValues[0:cap(pathValues)] // resize slice to maximum capacity so we can index set values
794 }
795
796 req := c.Request()
797 path := req.URL.Path
798 if !r.useEscapedPathForRouting && req.URL.RawPath != "" {
799 // Difference between URL.RawPath and URL.Path is:
800 // * URL.Path is where request path is stored. Value is stored in decoded form: /%47%6f%2f becomes /Go/.
801 // * URL.RawPath is an optional field which only gets set if the default encoding is different from Path.
802 path = req.URL.RawPath
803 }
804 var (
805 currentNode = r.tree // root as current node
806 previousBestMatchNode *node
807 matchedRouteMethod *routeMethod
808 // search stores the remaining path to check for match. By each iteration we move from start of path to end of the path
809 // and search value gets shorter and shorter.
810 search = path
811 searchIndex = 0
812 paramIndex int // Param counter
813 )
814
815 // Backtracking is needed when a dead end (leaf node) is reached in the router tree.
816 // To backtrack the current node will be changed to the parent node and the next kind for the
817 // router logic will be returned based on fromKind or kind of the dead end node (static > param > any).
818 // For example if there is no static node match we should check parent next sibling by kind (param).
819 // Backtracking itself does not check if there is a next sibling, this is done by the router logic.
820 backtrackToNextNodeKind := func(fromKind kind) (nextNodeKind kind, valid bool) {
821 previous := currentNode
822 currentNode = previous.parent
823 valid = currentNode != nil
824
825 // Next node type by priority
826 if previous.kind == anyKind {
827 nextNodeKind = staticKind
828 } else {
829 nextNodeKind = previous.kind + 1
830 }
831
832 if fromKind == staticKind {
833 // when backtracking is done from static kind block we did not change search so nothing to restore
834 return
835 }
836
837 // restore search to value it was before we move to current node we are backtracking from.
838 if previous.kind == staticKind {
839 searchIndex -= len(previous.prefix)
840 } else {
841 paramIndex--
842 // for param/any node.prefix value is always `:` so we can not deduce searchIndex from that and must use pValue
843 // for that index as it would also contain part of path we cut off before moving into node we are backtracking from
844 searchIndex -= len(pathValues[paramIndex].Value)
845 pathValues[paramIndex].Value = ""

Callers

nothing calls this directly

Calls 7

PathValuesMethod · 0.80
RequestMethod · 0.80
findMethod · 0.80
findStaticChildMethod · 0.80
InitializeRouteMethod · 0.80
SetMethod · 0.80
SetPathMethod · 0.80

Tested by

no test coverage detected