Skip to content

Commit fda86cd

Browse files
committed
chi router: sync with go version
1 parent 8563fd7 commit fda86cd

File tree

3 files changed

+79
-9
lines changed

3 files changed

+79
-9
lines changed

jooby/src/main/java/io/jooby/internal/Chi.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import java.util.stream.Stream;
1919

2020
/**
21-
* Sync: 20-01-20
22-
* Commit: 17fb1065d2b256d20f68bed0b7bca6c2942aff49
21+
* Sync: May 22, 2020
22+
* Commit: 5704d7ee98edd3fe55169b506531bdd061667c70
2323
*/
2424
class Chi implements RouteTree {
2525
private static final String EMPTY_STRING = "";
@@ -320,7 +320,7 @@ Node addChild(Node child, String search) {
320320

321321
if (segTyp == ntRegexp) {
322322
child.prefix = seg.rexPat;
323-
child.rex = Pattern.compile(seg.rexPat.toString());
323+
child.rex = Pattern.compile(seg.rexPat);
324324
}
325325

326326
if (segStartIdx == 0) {
@@ -471,7 +471,7 @@ Route findRoute(RouterMatch rctx, String method, String path) {
471471
}
472472

473473
if (ntyp == ntRegexp && xn.rex != null) {
474-
if (!xn.rex.matcher(xsearch.substring(0, p).toString()).matches()) {
474+
if (!xn.rex.matcher(xsearch.substring(0, p)).matches()) {
475475
continue;
476476
}
477477
} else if (xsearch.substring(0, p).indexOf('/') != -1) {
@@ -480,12 +480,32 @@ Route findRoute(RouterMatch rctx, String method, String path) {
480480
}
481481

482482
// rctx.routeParams.Values = append(rctx.routeParams.Values, xsearch[:p])
483+
int prevlen = rctx.vars.size();
483484
rctx.value(xsearch.substring(0, p));
484485
xsearch = xsearch.substring(p);
485-
break;
486+
487+
if (xsearch.length() == 0) {
488+
if (xn.isLeaf()) {
489+
Route h = xn.endpoints.get(method);
490+
if (h != null) {
491+
rctx.key(h.getPathKeys());
492+
return h;
493+
}
494+
rctx.methodNotAllowed(xn.endpoints.keySet());
495+
}
496+
}
497+
498+
// recursively find the next node on this branch
499+
Route fin = xn.findRoute(rctx, method, xsearch);
500+
if (fin != null) {
501+
return fin;
502+
}
503+
504+
// not found on this branch, reset vars
505+
rctx.truncate(prevlen);
506+
xsearch = path;
486507
}
487508
break;
488-
489509
default:
490510
// catch-all nodes
491511
// rctx.routeParams.Values = append(rctx.routeParams.Values, search)
@@ -649,7 +669,7 @@ Segment patNextSegment(String pattern) {
649669
int idx = key.indexOf(':');
650670
if (idx >= 0) {
651671
nt = ntRegexp;
652-
rexpat = key.substring(idx + 1).toString();
672+
rexpat = key.substring(idx + 1);
653673
// key = key.substring(0, idx);
654674
}
655675

jooby/src/main/java/io/jooby/internal/RouterMatch.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class RouterMatch implements Router.Match {
2323

2424
private Route route;
2525

26-
private Map vars = Collections.EMPTY_MAP;
26+
Map vars = Collections.EMPTY_MAP;
2727

2828
private Route.Handler handler;
2929

@@ -36,6 +36,12 @@ public void key(List<String> keys) {
3636
}
3737
}
3838

39+
public void truncate(int size) {
40+
while (size < vars.size()) {
41+
vars.remove(size++);
42+
}
43+
}
44+
3945
public void value(String value) {
4046
if (vars == Collections.EMPTY_MAP) {
4147
vars = new LinkedHashMap();

tests/src/test/java/io/jooby/FeaturedTest.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2945,7 +2945,7 @@ public void rawVsDecodedValues(ServerTestRunner runner) {
29452945
app.post("/form", ctx -> ctx.form("v").value());
29462946

29472947
app.post("/multipart", ctx -> ctx.multipart("v").value());
2948-
}).ready(client-> {
2948+
}).ready(client -> {
29492949
client.get("/path/a+b%2f", rsp -> {
29502950
assertEquals("a+b/", rsp.body().string().trim());
29512951
});
@@ -2973,6 +2973,50 @@ public void rawVsDecodedValues(ServerTestRunner runner) {
29732973
});
29742974
}
29752975

2976+
@ServerTest
2977+
public void recursiveRegexMatch(ServerTestRunner runner) {
2978+
runner.define(app -> {
2979+
app.get("/one/{firstId:[a-z0-9-]+}/{secondId:[a-z0-9-]+}/first",
2980+
ctx -> "/1/" + ctx.path("firstId").value() + "::" + ctx.path("secondId").value());
2981+
2982+
app.get("/one/{firstId:[a-z0-9-_]+}/{secondId:[a-z0-9-_]+}/second",
2983+
ctx -> "/2/" + ctx.path("firstId").value() + "::" + ctx.path("secondId").value());
2984+
}).ready(client -> {
2985+
client.get("/one/hello/peter/first", rsp -> {
2986+
assertEquals("/1/hello::peter", rsp.body().string());
2987+
});
2988+
client.get("/one/hithere/123/second", rsp -> {
2989+
assertEquals("/2/hithere::123", rsp.body().string());
2990+
});
2991+
});
2992+
}
2993+
2994+
@ServerTest
2995+
public void methodNotAllowedWithPathVariables(ServerTestRunner runner) {
2996+
runner.define(app -> {
2997+
app.get("/{var}", Context::getRequestPath);
2998+
}).ready(client -> {
2999+
client.delete("/foo", rsp -> {
3000+
assertEquals(405, rsp.code());
3001+
});
3002+
3003+
client.get("/foo", rsp -> {
3004+
assertEquals(200, rsp.code());
3005+
});
3006+
});
3007+
}
3008+
3009+
@ServerTest
3010+
public void regexpRoutingShouldIncludeDefaultValueWhenParamIsNotMatched(ServerTestRunner runner) {
3011+
runner.define(app -> {
3012+
app.get("/foo-{suffix:[a-z]{2,3}}.json", ctx -> ctx.path("suffix").value());
3013+
}).ready(client -> {
3014+
client.get("/foo-abc.json", rsp -> {
3015+
assertEquals("abc", rsp.body().string());
3016+
});
3017+
});
3018+
}
3019+
29763020
private byte[][] partition(byte[] bytes, int size) {
29773021
List<byte[]> result = new ArrayList<>();
29783022
int offset = 0;

0 commit comments

Comments
 (0)