Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(520)

Side by Side Diff: pkg/shelf/lib/src/cascade.dart

Issue 258633006: Add a Cascade helper to Shelf. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/shelf/lib/shelf.dart ('k') | pkg/shelf/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library shelf.cascade;
6
7 import 'handler.dart';
8 import 'response.dart';
9 import 'util.dart';
10
11 /// A typedef for [Cascade._shouldCascade].
12 typedef bool _ShouldCascade(Response response);
13
14 /// A helper that calls several handlers in sequence and returns the first
15 /// acceptable response.
16 ///
17 /// By default, a response is considered acceptable if it has a status other
18 /// than 404 or 405; other statuses indicate that the handler understood the
19 /// request.
20 ///
21 /// If all handlers return unacceptable responses, the final response will be
22 /// returned.
23 ///
24 /// var handler = new Cascade()
25 /// .add(webSocketHandler)
26 /// .add(staticFileHandler)
27 /// .add(application)
28 /// .handler;
29 class Cascade {
30 /// The function used to determine whether the cascade should continue on to
31 /// the next handler.
32 final _ShouldCascade _shouldCascade;
33
34 final Cascade _parent;
35 final Handler _handler;
36
37 /// Creates a new, empty cascade.
38 ///
39 /// If [statusCodes] is passed, responses with those status codes are
40 /// considered unacceptable. If [shouldCascade] is passed, responses for which
41 /// it returns `true` are considered unacceptale. [statusCode] and
42 /// [shouldCascade] may not both be passed.
43 Cascade({Iterable<int> statusCodes, bool shouldCascade(Response response)})
44 : _shouldCascade = _computeShouldCascade(statusCodes, shouldCascade),
45 _parent = null,
46 _handler = null {
47 if (statusCodes != null && shouldCascade != null) {
48 throw new ArgumentError("statusCodes and shouldCascade may not both be "
49 "passed.");
50 }
51 }
52
53 Cascade._(this._parent, this._handler, this._shouldCascade);
54
55 /// Returns a new cascade with [handler] added to the end.
56 ///
57 /// [handler] will only be called if all previous handlers in the cascade
58 /// return unacceptable responses.
59 Cascade add(Handler handler) => new Cascade._(this, handler, _shouldCascade);
60
61 /// Exposes this cascade as a single handler.
62 ///
63 /// This handler will call each inner handler in the cascade until one returns
64 /// an acceptable response, and return that. If no inner handlers return an
65 /// acceptable response, this will return the final response.
66 Handler get handler {
67 if (_handler == null) {
68 throw new StateError("Can't get a handler for a cascade with no inner "
69 "handlers.");
70 }
71
72 return (request) {
73 if (_parent._handler == null) return _handler(request);
74 return syncFuture(() => _parent.handler(request)).then((response) {
75 if (_shouldCascade(response)) return _handler(request);
76 return response;
77 });
78 };
79 }
80 }
81
82 /// Computes the [Cascade._shouldCascade] function based on the user's
83 /// parameters.
84 Function _computeShouldCascade(Iterable<int> statusCodes,
kevmoo 2014/04/25 21:55:11 Woulda coulda used typedef here, too :-)
85 Function shouldCascade) {
86 if (shouldCascade != null) return shouldCascade;
87 if (statusCodes == null) statusCodes = [404, 405];
88 statusCodes = statusCodes.toSet();
89 return (response) => statusCodes.contains(response.statusCode);
90 }
OLDNEW
« no previous file with comments | « pkg/shelf/lib/shelf.dart ('k') | pkg/shelf/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698