| // Copyright (c) 2015, 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. |
| |
| import 'dart:async'; |
| import 'package:path/path.dart' as p; |
| import 'package:shelf/shelf.dart' as shelf; |
| |
| /// A Shelf handler that provides support for one-time handlers. |
| /// |
| /// This is useful for handlers that only expect to be hit once before becoming |
| /// invalid and don't need to have a persistent URL. |
| class OneOffHandler { |
| /// A map from URL paths to handlers. |
| final _handlers = <String, shelf.Handler>{}; |
| |
| /// The counter of handlers that have been activated. |
| var _counter = 0; |
| |
| /// The actual [shelf.Handler] that dispatches requests. |
| shelf.Handler get handler => _onRequest; |
| |
| /// Creates a new one-off handler that forwards to [handler]. |
| /// |
| /// Returns a string that's the URL path for hitting this handler, relative to |
| /// the URL for the one-off handler itself. |
| /// |
| /// [handler] will be unmounted as soon as it receives a request. |
| String create(shelf.Handler handler) { |
| var path = _counter.toString(); |
| _handlers[path] = handler; |
| _counter++; |
| return path; |
| } |
| |
| /// Dispatches [request] to the appropriate handler. |
| FutureOr<shelf.Response> _onRequest(shelf.Request request) { |
| var components = p.url.split(request.url.path); |
| if (components.isEmpty) return shelf.Response.notFound(null); |
| |
| var path = components.removeAt(0); |
| var handler = _handlers.remove(path); |
| if (handler == null) return shelf.Response.notFound(null); |
| return handler(request.change(path: path)); |
| } |
| } |