blob: c07799ab2348fdeef4eaef950c5410470868c609 [file] [log] [blame]
// 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.
//
// @dart=2.7
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));
}
}