Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Commit 51b1952

Browse files
committed
New feature: If a route has matchSubPaths = true, the requested subpath can be assigned to a parameter
1 parent cdd3abb commit 51b1952

File tree

6 files changed

+42
-16
lines changed

6 files changed

+42
-16
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## v0.5.12
2+
* New feature: If a route has `matchSubPaths = true`, the requested subpath can be assigned to a parameter (see issue #36).
3+
14
## v0.5.11
25
* Minor performance fix: Redstone.dart shouldn't create a new `shelf.Pipeline` per request.
36

lib/server.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ void setUp([List<Symbol> libraries]) {
459459
_scanHandlers(libraries);
460460
} catch (e) {
461461
_handleError("Failed to configure handlers.", e);
462-
throw e;
462+
rethrow;
463463
}
464464
}
465465

lib/src/setup_impl.dart

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,13 @@ class _Target {
5757
UrlMatch match(Uri uri) {
5858
UrlMatch match = urlTemplate.match(uri.path);
5959
if (match != null) {
60-
if (route.matchSubPaths) {
61-
if (uri.path.endsWith("/") || match.tail.startsWith("/")) {
62-
return match;
63-
}
64-
} else {
65-
if (match.tail.isEmpty) {
66-
return match;
67-
}
60+
if (match.tail.isEmpty) {
61+
return match;
62+
} else if (route.matchSubPaths &&
63+
(uri.path.endsWith("/") || match.tail.startsWith("/"))) {
64+
return match;
6865
}
6966
}
70-
71-
if (match != null && match.tail.isEmpty) {
72-
return match;
73-
}
7467
return null;
7568
}
7669

@@ -721,6 +714,7 @@ void _configureTarget(_ServerMetadataImpl serverMetadata,
721714

722715
var responseProcessors = null;
723716
var wrapper = null;
717+
var specialPathParam = null;
724718

725719
var caller = (UrlMatch match, Request request) {
726720

@@ -771,6 +765,10 @@ void _configureTarget(_ServerMetadataImpl serverMetadata,
771765
return new Future(() {
772766

773767
var pathParams = match.parameters;
768+
769+
if (specialPathParam != null) {
770+
pathParams[specialPathParam] = pathParams[specialPathParam] + match.tail;
771+
}
774772

775773
var posParams = [];
776774
var namedParams = {};
@@ -815,12 +813,25 @@ void _configureTarget(_ServerMetadataImpl serverMetadata,
815813

816814
};
817815

818-
String url = route.urlTemplate;
816+
String url = route.urlTemplate.trim();
819817
if (urlPrefix != null) {
820818
url = _joinUrl(urlPrefix, url);
821819
}
820+
821+
var originalUrl = url;
822+
if (url.endsWith("*")) {
823+
url = url.substring(0, url.length - 1);
824+
}
822825

823826
UrlTemplate urlTemplate = new UrlTemplate(url);
827+
828+
if (route.matchSubPaths && urlTemplate.urlParameterNames().isNotEmpty) {
829+
var lastParam = urlTemplate.urlParameterNames().last;
830+
if (originalUrl.endsWith(":$lastParam*")) {
831+
specialPathParam = lastParam;
832+
}
833+
}
834+
824835
_Target target;
825836
if (paramProcessors.bodyType == null) {
826837
target = new _Target(urlTemplate, handlerName, caller, route);

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: redstone
2-
version: 0.5.11
2+
version: 0.5.12
33
author: Luiz Mineo <[email protected]>
44
description: A metadata driven microframework for Dart
55
homepage: http://redstonedart.org
@@ -9,7 +9,7 @@ dependencies:
99
collection: '>=0.9.3+1 <0.10.0'
1010
crypto: '>=0.9.0 <0.10.0'
1111
grinder: '>=0.5.2 <0.6.0'
12-
route_hierarchical: '>=0.4.21 <0.5.0'
12+
route_hierarchical: '>=0.4.22 <0.5.0'
1313
di: ">=2.0.1 <3.0.0"
1414
shelf: ">=0.5.4+2 <0.6.0"
1515
mime: ">=0.9.0+1 <0.10.0"

test/server_tests.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,19 @@ main() {
3535
var req = new MockRequest("/path/subpath");
3636
var req2 = new MockRequest("/path/anotherpath");
3737
var req3 = new MockRequest("/paths");
38+
var req4 = new MockRequest("/path2/sub/path");
39+
var req5 = new MockRequest("/path3/sub/path");
3840

3941
return app.dispatch(req).then((resp) {
4042
expect(resp.mockContent, equals("sub_route"));
4143
}).then((_) => app.dispatch(req2)).then((resp) {
4244
expect(resp.mockContent, equals("main_route"));
4345
}).then((_) => app.dispatch(req3)).then((resp) {
4446
expect(resp.statusCode, equals(404));
47+
}).then((_) => app.dispatch(req4)).then((resp) {
48+
expect(resp.mockContent, equals("sub"));
49+
}).then((_) => app.dispatch(req5)).then((resp) {
50+
expect(resp.mockContent, equals("sub/path"));
4551
});
4652
});
4753

test/services/routes.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ mainRoute() => "main_route";
99
@app.Route("/path/subpath")
1010
subRoute() => "sub_route";
1111

12+
@app.Route("/path2/:param", matchSubPaths: true)
13+
mainRouteWithParam(String param) => param;
14+
15+
@app.Route("/path3/:param*", matchSubPaths: true)
16+
mainRouteWithSpecialParam(String param) => param;
17+
1218
@app.Route("/handler_by_method")
1319
getHandler() => "get_handler";
1420

0 commit comments

Comments
 (0)