18
18
19
19
part of '_internal.dart' ;
20
20
21
+ /// Middleware to remove body from request.
22
+ Handler _removeBody (Handler handler) {
23
+ return (context) async {
24
+ var response = await handler (context);
25
+ if (response.headers.containsKey ('content-length' )) {
26
+ response = response.copyWith (headers: {'content-length' : '0' });
27
+ }
28
+ return response.copyWith (body: < int > []);
29
+ };
30
+ }
31
+
21
32
/// A class that routes requests to handlers based on HTTP verb and route
22
33
/// pattern.
23
34
class Router {
@@ -31,6 +42,27 @@ class Router {
31
42
final List <RouterEntry > _routes = [];
32
43
final Handler _notFoundHandler;
33
44
45
+ /// Add [handler] for [verb] requests to [route] .
46
+ ///
47
+ /// If [verb] is `GET` the [handler] will also be called for `HEAD` requests
48
+ /// matching [route] . This is because handling `GET` requests without handling
49
+ /// `HEAD` is always wrong. To explicitely implement a `HEAD` handler it must
50
+ /// be registered before the `GET` handler.
51
+ void add (String verb, String route, Function handler) {
52
+ if (! isHttpMethod (verb)) {
53
+ throw ArgumentError .value (verb, 'verb' , 'expected a valid HTTP method' );
54
+ }
55
+
56
+ final _verb = verb.toUpperCase ();
57
+
58
+ if (_verb == 'GET' ) {
59
+ // Handling in a 'GET' request without handling a 'HEAD' request is always
60
+ // wrong, thus, we add a default implementation that discards the body.
61
+ _routes.add (RouterEntry ('HEAD' , route, handler, middleware: _removeBody));
62
+ }
63
+ _routes.add (RouterEntry (_verb, route, handler));
64
+ }
65
+
34
66
/// Handle all request to [route] using [handler] .
35
67
void all (String route, Function handler) {
36
68
_routes.add (RouterEntry ('ALL' , route, handler));
@@ -86,6 +118,33 @@ class Router {
86
118
return _notFoundHandler (context);
87
119
}
88
120
121
+ // Handlers for all methods
122
+
123
+ /// Handle `GET` request to [route] using [handler] .
124
+ ///
125
+ /// If no matching handler for `HEAD` requests is registered, such requests
126
+ /// will also be routed to the [handler] registered here.
127
+ void get (String route, Function handler) => add ('GET' , route, handler);
128
+
129
+ /// Handle `HEAD` request to [route] using [handler] .
130
+ void head (String route, Function handler) => add ('HEAD' , route, handler);
131
+
132
+ /// Handle `POST` request to [route] using [handler] .
133
+ void post (String route, Function handler) => add ('POST' , route, handler);
134
+
135
+ /// Handle `PUT` request to [route] using [handler] .
136
+ void put (String route, Function handler) => add ('PUT' , route, handler);
137
+
138
+ /// Handle `DELETE` request to [route] using [handler] .
139
+ void delete (String route, Function handler) => add ('DELETE' , route, handler);
140
+
141
+ /// Handle `OPTIONS` request to [route] using [handler] .
142
+ void options (String route, Function handler) =>
143
+ add ('OPTIONS' , route, handler);
144
+
145
+ /// Handle `PATCH` request to [route] using [handler] .
146
+ void patch (String route, Function handler) => add ('PATCH' , route, handler);
147
+
89
148
static Response _defaultNotFound (RequestContext context) => routeNotFound;
90
149
91
150
/// Sentinel [Response] object indicating that no matching route was found.
0 commit comments