:)
This commit is contained in:
parent
0057f11661
commit
530eb11bf8
5 changed files with 89 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
|||
# angel_framework
|
||||
|
||||
[![pub 1.0.0-dev.35](https://img.shields.io/badge/pub-1.0.0--dev.35-red.svg)](https://pub.dartlang.org/packages/angel_framework)
|
||||
[![pub 1.0.0-dev.36](https://img.shields.io/badge/pub-1.0.0--dev.36-red.svg)](https://pub.dartlang.org/packages/angel_framework)
|
||||
[![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework)
|
||||
|
||||
Core libraries for the Angel Framework.
|
|
@ -4,6 +4,11 @@ import 'dart:async';
|
|||
import 'request_context.dart';
|
||||
import 'response_context.dart';
|
||||
|
||||
abstract class AngelMiddleware {
|
||||
Future<bool> call(RequestContext req, ResponseContext res);
|
||||
}
|
||||
|
||||
@Deprecated('Use AngelMiddleware instead')
|
||||
abstract class BaseMiddleware {
|
||||
Future<bool> call(RequestContext req, ResponseContext res);
|
||||
}
|
|
@ -79,6 +79,8 @@ class ResponseContext extends Extensible {
|
|||
ResponseContext(this.io, this.app);
|
||||
|
||||
/// Set this to true if you will manually close the response.
|
||||
///
|
||||
/// If `true`, all response finalizers will be skipped.
|
||||
bool willCloseItself = false;
|
||||
|
||||
/// Sends a download as a response.
|
||||
|
@ -209,14 +211,34 @@ class ResponseContext extends Extensible {
|
|||
redirect('$head/$tail'.replaceAll(_straySlashes, ''), code: code);
|
||||
}
|
||||
|
||||
/// Streams a file to this response as chunked data.
|
||||
Future streamFile(File file,
|
||||
/// Copies a file's contents into the response buffer.
|
||||
Future sendFile(File file,
|
||||
{int chunkSize, int sleepMs: 0, bool resumable: true}) async {
|
||||
if (!isOpen) return;
|
||||
|
||||
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
||||
end();
|
||||
buffer.add(await file.readAsBytes());
|
||||
end();
|
||||
}
|
||||
|
||||
/// Streams a file to this response.
|
||||
///
|
||||
/// You can optionally transform the file stream with a [codec].
|
||||
Future streamFile(File file,
|
||||
{int chunkSize,
|
||||
int sleepMs: 0,
|
||||
bool resumable: true,
|
||||
Codec<List<int>, List<int>> codec}) async {
|
||||
if (!isOpen) return;
|
||||
|
||||
headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path);
|
||||
end();
|
||||
willCloseItself = true;
|
||||
|
||||
var stream = codec != null
|
||||
? file.openRead().transform(codec.encoder)
|
||||
: file.openRead();
|
||||
await stream.pipe(io);
|
||||
}
|
||||
|
||||
/// Writes data to the response.
|
||||
|
|
|
@ -38,6 +38,8 @@ class Angel extends AngelBase {
|
|||
new StreamController<AngelFatalError>.broadcast();
|
||||
StreamController<Controller> _onController =
|
||||
new StreamController<Controller>.broadcast();
|
||||
final List<Angel> _children = [];
|
||||
Angel _parent;
|
||||
final Random _rand = new Random.secure();
|
||||
|
||||
ServerGenerator _serverGenerator = HttpServer.bind;
|
||||
|
@ -48,14 +50,26 @@ class Angel extends AngelBase {
|
|||
/// Fired before a request is processed. Always runs.
|
||||
Stream<HttpRequest> get beforeProcessed => _beforeProcessed.stream;
|
||||
|
||||
/// All child application mounted on this instance.
|
||||
List<Angel> get children => new List<Angel>.unmodifiable(_children);
|
||||
|
||||
/// Fired on fatal errors.
|
||||
Stream<AngelFatalError> get fatalErrorStream => _fatalErrorStream.stream;
|
||||
|
||||
/// Indicates whether the application is running in a production environment.
|
||||
///
|
||||
/// The criteria for this is the `ANGEL_ENV` environment variable being set to
|
||||
/// `'production'`.
|
||||
bool get isProduction => Platform.environment['ANGEL_ENV'] == 'production';
|
||||
|
||||
/// Fired whenever a controller is added to this instance.
|
||||
///
|
||||
/// **NOTE**: This is a broadcast stream.
|
||||
Stream<Controller> get onController => _onController.stream;
|
||||
|
||||
/// Returns the parent instance of this application, if any.
|
||||
Angel get parent => _parent;
|
||||
|
||||
/// Always run before responses are sent.
|
||||
///
|
||||
/// These will only not run if an [AngelFatalError] occurs.
|
||||
|
@ -79,10 +93,10 @@ class Angel extends AngelBase {
|
|||
AngelErrorHandler get errorHandler => _errorHandler;
|
||||
|
||||
/// [RequestMiddleware] to be run before all requests.
|
||||
List before = [];
|
||||
final List before = [];
|
||||
|
||||
/// [RequestMiddleware] to be run after all requests.
|
||||
List after = [];
|
||||
final List after = [];
|
||||
|
||||
/// The native HttpServer running this instancce.
|
||||
HttpServer httpServer;
|
||||
|
@ -254,7 +268,7 @@ class Angel extends AngelBase {
|
|||
for (var key in res.headers.keys) {
|
||||
request.response.headers.set(key, res.headers[key]);
|
||||
}
|
||||
|
||||
|
||||
request.response.headers.chunkedTransferEncoding = res.chunked ?? true;
|
||||
|
||||
request.response
|
||||
|
@ -327,16 +341,55 @@ class Angel extends AngelBase {
|
|||
}, onError: _onError);
|
||||
}
|
||||
|
||||
/// Mounts the child on this router.
|
||||
///
|
||||
/// If the router is an [Angel] instance, all controllers
|
||||
/// will be copied, as well as services and response finalizers.
|
||||
///
|
||||
/// [before] and [after] will be preserved.
|
||||
///
|
||||
/// NOTE: The above will not be properly copied if [path] is
|
||||
/// a [RegExp].
|
||||
@override
|
||||
use(Pattern path, Routable routable,
|
||||
{bool hooked: true, String namespace: null}) {
|
||||
final head = path.toString().replaceAll(_straySlashes, '');
|
||||
|
||||
if (routable is Angel) {
|
||||
final head = path.toString().replaceAll(_straySlashes, '');
|
||||
_children.add(routable.._parent = this);
|
||||
|
||||
if (routable.before.isNotEmpty) {
|
||||
all(path, (req, res) {
|
||||
return true;
|
||||
}, middleware: routable.before);
|
||||
}
|
||||
|
||||
if (routable.after.isNotEmpty) {
|
||||
all(path, (req, res) {
|
||||
return true;
|
||||
}, middleware: routable.after);
|
||||
}
|
||||
|
||||
if (routable.responseFinalizers.isNotEmpty) {
|
||||
responseFinalizers.add((req, res) async {
|
||||
if (req.path.replaceAll(_straySlashes, '').startsWith(head)) {
|
||||
for (var finalizer in routable.responseFinalizers)
|
||||
await finalizer(req, res);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
routable.controllers.forEach((k, v) {
|
||||
final tail = k.toString().replaceAll(_straySlashes, '');
|
||||
controllers['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
||||
});
|
||||
|
||||
routable.services.forEach((k, v) {
|
||||
final tail = k.toString().replaceAll(_straySlashes, '');
|
||||
services['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
||||
});
|
||||
}
|
||||
|
||||
if (routable is Service) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: angel_framework
|
||||
version: 1.0.0-dev.35
|
||||
version: 1.0.0-dev.36
|
||||
description: Core libraries for the Angel framework.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/angel_framework
|
||||
|
|
Loading…
Reference in a new issue