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

Unified 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: Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/shelf/lib/shelf.dart ('k') | pkg/shelf/pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/shelf/lib/src/cascade.dart
diff --git a/pkg/shelf/lib/src/cascade.dart b/pkg/shelf/lib/src/cascade.dart
new file mode 100644
index 0000000000000000000000000000000000000000..40911d45f689b61acae96e626ab02e36ef8d75cd
--- /dev/null
+++ b/pkg/shelf/lib/src/cascade.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library shelf.cascade;
+
+import 'handler.dart';
+import 'middleware.dart';
+import 'response.dart';
+import 'util.dart';
+
+/// A helper that calls several handlers in sequence and returns the first
+/// acceptable response.
+///
+/// By default, a response is considered acceptable if it has a status other
+/// than 404 or 405; other statuses indicate that the handler understood the
+/// request.
+///
+/// If all handlers return unacceptable responses, the final response will be
+/// returned.
+///
+/// var handler = const Cascade()
kevmoo 2014/04/25 00:32:31 Where's the const ctor?
nweiz 2014/04/25 00:54:56 Just a documentation error, this should be "new".
kevmoo 2014/04/25 13:26:05 Actually, taking in a callback is fine. Having a b
+/// .add(webSocketHandler)
+/// .add(staticFileHandler)
+/// .add(application)
+/// .handler;
+class Cascade {
+ /// The function used to determine whether the cascade should continue on to
+ /// the next handler.
+ final Function _shouldCascade;
+
+ final Cascade _parent;
+ final Handler _handler;
+
+ /// Creates a new, empty cascade.
+ ///
+ /// If [statusCodes] is passed, responses with those status codes are
+ /// considered unacceptable. If [shouldCascade] is passed, responses for which
+ /// it returns `true` are considered unacceptale. [statusCode] and
+ /// [shouldCascade] may not both be passed.
+ Cascade({Iterable<int> statusCodes, bool shouldCascade(Response response)})
+ : _shouldCascade = _computeShouldCascade(statusCodes, shouldCascade),
+ _parent = null,
+ _handler = null {
+ if (statusCodes != null && shouldCascade != null) {
+ throw new ArgumentError("statusCodes and shouldCascade may not both be "
+ "passed.");
+ }
+ }
+
+ Cascade._(this._parent, this._handler, this._shouldCascade);
+
+ /// Returns a new cascade with [handler] added to the end.
+ ///
+ /// [handler] will only be called if all previous handlers in the cascade
+ /// return unacceptable responses.
+ Cascade add(Handler handler) => new Cascade._(this, handler, _shouldCascade);
+
+ /// Exposes this cascade as a single handler.
+ ///
+ /// This handler will call each inner handler in the cascade until one returns
+ /// an acceptable response, and return that. If no inner handlers return an
+ /// acceptable response, this will return the final response.
+ Handler get handler {
+ if (_handler == null) {
+ throw new StateError("Can't get a handler for a cascade with no inner "
+ "handlers.");
+ }
+
+ return (request) {
+ if (_parent._handler == null) return _handler(request);
+ return syncFuture(() => _parent.handler(request)).then((response) {
+ if (_shouldCascade(response)) return _handler(request);
+ return response;
+ });
+ };
+ }
+}
+
+/// Computes the [Cascade._shouldCascade] function based on the user's
+/// parameters.
+Function _computeShouldCascade(Iterable<int> statusCodes,
+ Function shouldCascade) {
+ if (shouldCascade != null) return shouldCascade;
+ if (statusCodes == null) statusCodes = [404, 405];
+ statusCodes = statusCodes.toSet();
+ return (response) => statusCodes.contains(response.statusCode);
+}
« 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