Repository navigation
Commit f085ffb
authored
fix(router): handle escaped colons and inline verbs in v4 (#3132)
* fix(router): keep escaped colon and parameter routes reachable in v4
* fix(router): parse inline verbs consistently in v4
* fix(router): backtrack inline verb splits in v4
* perf(router): preserve v4 fast path without inline verbs
* fix(router): retry inline verb splits on the param node in v4
Backport of the v5 change. Replace the whole-search retry plan with a
backtrack point on the param node: when a candidate split fails, the
same param node is retried with the next literal-colon split and finally
the whole path segment before routing backtracks to its parent. Static >
param > any priority of ancestors, the leaf rule of later params, group
middleware and catch-all routes are no longer affected by a failed split.
An escaped colon after a parameter starts an inline verb only when the
rest of that path segment is static (`/:name\:cancel`, optionally
followed by `/...`). Split candidates are then scanned once per segment,
so a request with many colons is routed in linear time. Other escaped
colons after a parameter keep their older meaning as part of the
parameter name.
The duplicated fast-path Find and the router-level inline verb flag are
removed. The param scan uses strings.IndexByte, which keeps router
benchmarks within about 0.3% of v4 (geomean).
* fix(router): retry inline verb splits after a wildcard fails
A wildcard ends the route search, but a param value above it that ended
at an inline verb split is now retried with the next split and the whole
segment, so a verb route with a wildcard cannot shadow a generic route
for other methods.
The retry now runs only when routing backtracks from the inline verb
child into its param node, instead of on every dead end.
An escaped colon after a parameter keeps its older meaning (part of the
parameter name) unless the first one in the segment starts an inline
verb, so a later `\:` cannot turn such a legacy route into a verb route.
Reverse writes placeholders for such names without the backslash, as
before. Dead hasColonChild bookkeeping for split nodes is removed.
* fix(router): keep backtracking below an inline verb split
When a wildcard fails below a param value that ended at an inline verb
split, keep backtracking one node at a time instead of jumping to that
param node, so the other routes below the split are tried before the
next split. Without a pending split a failed wildcard still ends the
search as before, and the check does not change the routing state.
Adds tests for nested splits, routes below a split and a RouteNotFound
wildcard below a split.
* fix(router): keep escaped colons after complex param names in v4
An escaped colon after a param name that contains ':' or '*' keeps its
older meaning as part of the name. The escaped colon check is shared in
the route syntax scanner. Adds tests for RouteNotFound on the whole
segment and Reverse placeholders.
* fix(router): keep leaf params matching the rest of the path
Registering an inline verb route under a param gave the param node a
static child, so a sibling route ending in that param (`/files/:path`)
stopped matching values across slashes. When the inline verb child is
the node's only child, a param value without a split now takes the rest
of the path, as a leaf param does.
* test(router): cover leaf param fallbacks next to an inline verb
Drop the param and any child checks that cannot fail for a param node, and pin 405, RouteNotFound and wildcard fallbacks for a param value that spans slashes next to an inline verb route.1 parent 5440f99 commit f085ffb
4 files changed
Lines changed: 633 additions & 60 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
0 commit comments