| 394 | } |
| 395 | |
| 396 | func (n *Node) getNode(path string) *Node { |
| 397 | walk: // outer loop for walking the tree |
| 398 | for { |
| 399 | if len(path) > len(n.path) { |
| 400 | if path[:len(n.path)] == n.path { |
| 401 | path = path[len(n.path):] |
| 402 | // If this node does not have a wildcard (param or catchAll) |
| 403 | // child, we can just look up the next child node and continue |
| 404 | // to walk down the tree |
| 405 | if !n.wildChild { |
| 406 | c := path[0] |
| 407 | for i := 0; i < len(n.indices); i++ { |
| 408 | if c == n.indices[i] { |
| 409 | n = n.children[i] |
| 410 | continue walk |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | // Nothing found. |
| 415 | // We can recommend to redirect to the same URL without a |
| 416 | // trailing slash if a leaf exists for that path. |
| 417 | return nil |
| 418 | |
| 419 | } |
| 420 | |
| 421 | // handle wildcard child |
| 422 | n = n.children[0] |
| 423 | switch n.nType { |
| 424 | case param: |
| 425 | // find param end (either '/' or path end) |
| 426 | end := 0 |
| 427 | for end < len(path) && path[end] != '/' { |
| 428 | end++ |
| 429 | } |
| 430 | |
| 431 | // we need to go deeper! |
| 432 | if end < len(path) { |
| 433 | if len(n.children) > 0 { |
| 434 | path = path[end:] |
| 435 | n = n.children[0] |
| 436 | continue walk |
| 437 | } |
| 438 | |
| 439 | // ... but we can't |
| 440 | return nil |
| 441 | } |
| 442 | |
| 443 | return n |
| 444 | |
| 445 | case catchAll: |
| 446 | return n |
| 447 | default: |
| 448 | panic("invalid node type") |
| 449 | } |
| 450 | } |
| 451 | } else if path == n.path { |
| 452 | return n |
| 453 | } |