Skip to content

Commit

Permalink
Fix mixing static + wildcard segment causes hung request #37
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio Andres Virviescas Santana committed Jul 23, 2020
1 parent d5d344c commit b310583
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
32 changes: 30 additions & 2 deletions radix/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ func (n *node) insert(path, fullPath string, handler fasthttp.RequestHandler) (*

switch wp.pType {
case param:
// newNode.path = newNode.path[:wp.end]
n.hasWildChild = true

child.nType = wp.pType
child.paramKeys = wp.keys
child.paramRegex = wp.regex
Expand Down Expand Up @@ -273,9 +274,15 @@ func (n *node) add(path, fullPath string, handler fasthttp.RequestHandler) (*nod
}

func (n *node) getFromChild(path string, ctx *fasthttp.RequestCtx) (fasthttp.RequestHandler, bool) {
var parent *node

parentIndex, childIndex := 0, 0

walk:
for {
for _, child := range n.children {
for _, child := range n.children[childIndex:] {
childIndex++

switch child.nType {
case static:

Expand All @@ -292,7 +299,12 @@ walk:

path = path[len(child.path):]

parent = n
n = child

parentIndex = childIndex
childIndex = 0

continue walk

} else if path == child.path {
Expand Down Expand Up @@ -356,6 +368,22 @@ walk:
default:
panic("invalid node type")
}

}

// Go back and continue with the remaining children of the parent
// to try to discover the correct child node
// if the parent has a child node of type param
//
// See: https://github.com/fasthttp/router/issues/37
if parent != nil && parent.hasWildChild && len(parent.children[parentIndex:]) > 0 {
path = n.path + path
childIndex = parentIndex

n = parent
parent = nil

continue walk
}

if n.wildcard != nil {
Expand Down
6 changes: 6 additions & 0 deletions radix/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ func TestTreeAddAndGet(t *testing.T) {
"/doc/go1.html",
"/α",
"/β",
"/hello/test",
"/hello/{name}",
}

for _, route := range routes {
Expand All @@ -134,6 +136,10 @@ func TestTreeAddAndGet(t *testing.T) {
{"/ab", false, "/ab", nil},
{"/α", false, "/α", nil},
{"/β", false, "/β", nil},
{"/hello/test", false, "/hello/test", nil},
{"/hello/test1", false, "/hello/{name}", map[string]interface{}{"name": "test1"}},
{"/hello/tes", false, "/hello/{name}", map[string]interface{}{"name": "tes"}},
{"/hello/test/bye", true, "", nil},
})
}

Expand Down
11 changes: 6 additions & 5 deletions radix/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ type nodeWildcard struct {
type node struct {
nType nodeType

path string
tsr bool
handler fasthttp.RequestHandler
children []*node
wildcard *nodeWildcard
path string
tsr bool
handler fasthttp.RequestHandler
hasWildChild bool
children []*node
wildcard *nodeWildcard

paramKeys []string
paramRegex *regexp.Regexp
Expand Down

0 comments on commit b310583

Please sign in to comment.