From 4c9db6f9327efbec74958cdd3aa5900a47433ccf Mon Sep 17 00:00:00 2001 From: regiostech Date: Tue, 5 Jul 2016 18:11:54 -0400 Subject: [PATCH] onService, onController --- lib/src/http/controller.dart | 2 ++ lib/src/http/routable.dart | 12 +++++++++++- lib/src/http/server.dart | 33 ++++++++++++++++++++++++--------- pubspec.yaml | 2 +- test/services.dart | 1 + 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/src/http/controller.dart b/lib/src/http/controller.dart index 85d8b17d..369b9b7b 100644 --- a/lib/src/http/controller.dart +++ b/lib/src/http/controller.dart @@ -1,12 +1,14 @@ part of angel_framework.http; class Controller { + Angel app; List middleware = []; List routes = []; Map _mappings = {}; Expose exposeDecl; Future call(Angel app) async { + this.app = app; Routable routable = new Routable() ..routes.addAll(routes); app.use(exposeDecl.path, routable); diff --git a/lib/src/http/routable.dart b/lib/src/http/routable.dart index 3722a4b8..45a6637e 100644 --- a/lib/src/http/routable.dart +++ b/lib/src/http/routable.dart @@ -40,6 +40,13 @@ class Routable extends Extensible { /// A set of [Controller] objects that have been loaded into the application. Map controllers = {}; + StreamController _onService = new StreamController.broadcast(); + + /// Fired whenever a service is added to this instance. + /// + /// **NOTE**: This is a broadcast stream. + Stream get onService => _onService.stream; + /// Assigns a middleware to a name for convenience. registerMiddleware(String name, RequestMiddleware middleware) { this.requestMiddleware[name] = middleware; @@ -61,7 +68,7 @@ class Routable extends Extensible { /// For example, if the [Routable] has a middleware 'y', and the `middlewareNamespace` /// is 'x', then that middleware will be available as 'x.y' in the main application. /// These namespaces can be nested. - use(Pattern path, Routable routable, + void use(Pattern path, Routable routable, {bool hooked: true, String middlewareNamespace: null}) { Routable _routable = routable; @@ -115,6 +122,9 @@ class Routable extends Extensible { new RegExp(r'(^\/+)|(\/+$)'), '') + '/$servicePath'; services[newServicePath] = _routable.services[servicePath]; } + + if (routable is Service) + _onService.add(routable); } /// Adds a route that responds to the given path diff --git a/lib/src/http/server.dart b/lib/src/http/server.dart index b49329f1..7bc9bce0 100644 --- a/lib/src/http/server.dart +++ b/lib/src/http/server.dart @@ -4,8 +4,8 @@ part of angel_framework.http; typedef Future ServerGenerator(InternetAddress address, int port); /// Handles an [AngelHttpException]. -typedef Future AngelErrorHandler( - AngelHttpException err, RequestContext req, ResponseContext res); +typedef Future AngelErrorHandler(AngelHttpException err, RequestContext req, + ResponseContext res); /// A function that configures an [Angel] server in some way. typedef Future AngelConfigurer(Angel app); @@ -14,15 +14,25 @@ typedef Future AngelConfigurer(Angel app); class Angel extends Routable { var _beforeProcessed = new StreamController(); var _afterProcessed = new StreamController(); + var _onController = new StreamController.broadcast(); + /// Fired before a request is processed. Always runs. Stream get beforeProcessed => _beforeProcessed.stream; + + /// Fired after a request is processed. Always runs. Stream get afterProcessed => _afterProcessed.stream; + /// Fired whenever a controller is added to this instance. + /// + /// **NOTE**: This is a broadcast stream. + Stream get onController => _onController.stream; + ServerGenerator _serverGenerator = (address, port) async => await HttpServer.bind(address, port); /// Default error handler, show HTML error page - AngelErrorHandler _errorHandler = (AngelHttpException e, req, ResponseContext res) { + AngelErrorHandler _errorHandler = (AngelHttpException e, req, + ResponseContext res) { res.header(HttpHeaders.CONTENT_TYPE, ContentType.HTML.toString()); res.status(e.statusCode); res.write("${e.message}"); @@ -37,7 +47,8 @@ class Angel extends Routable { /// A function that renders views. /// /// Called by [ResponseContext]@`render`. - ViewGenerator viewGenerator = (String view, [Map data]) async => "No view engine has been configured yet."; + ViewGenerator viewGenerator = (String view, + [Map data]) async => "No view engine has been configured yet."; /// [RequestMiddleware] to be run before all requests. List before = []; @@ -53,7 +64,7 @@ class Angel extends Routable { /// Returns false on failure; otherwise, returns the HttpServer. startServer(InternetAddress address, int port) async { var server = - await _serverGenerator(address ?? InternetAddress.LOOPBACK_IP_V4, port); + await _serverGenerator(address ?? InternetAddress.LOOPBACK_IP_V4, port); this.httpServer = server; server.listen(handleRequest); @@ -64,7 +75,8 @@ class Angel extends Routable { Future handleRequest(HttpRequest request) async { _beforeProcessed.add(request); String req_url = - request.uri.toString().replaceAll("?" + request.uri.query, "").replaceAll(new RegExp(r'\/+$'), ''); + request.uri.toString().replaceAll("?" + request.uri.query, "").replaceAll( + new RegExp(r'\/+$'), ''); if (req_url.isEmpty) req_url = '/'; RequestContext req = await RequestContext.from(request, {}, this, null); ResponseContext res = await ResponseContext.from(request.response, this); @@ -122,8 +134,8 @@ class Angel extends Routable { _finalizeResponse(request, res); } - Future _applyHandler( - handler, RequestContext req, ResponseContext res) async { + Future _applyHandler(handler, RequestContext req, + ResponseContext res) async { if (handler is RequestMiddleware) { var result = await handler(req, res); if (result is bool) @@ -190,6 +202,9 @@ class Angel extends Routable { /// Applies an [AngelConfigurer] to this instance. Future configure(AngelConfigurer configurer) async { await configurer(this); + + if (configurer is Controller) + _onController.add(configurer); } /// Starts the server. @@ -231,7 +246,7 @@ class Angel extends Routable { : super() { _serverGenerator = (InternetAddress address, int port) async { var certificateChain = - Platform.script.resolve('server_chain.pem').toFilePath(); + Platform.script.resolve('server_chain.pem').toFilePath(); var serverKey = Platform.script.resolve('server_key.pem').toFilePath(); var serverContext = new SecurityContext(); serverContext.useCertificateChain(certificateChain); diff --git a/pubspec.yaml b/pubspec.yaml index 5fdf2a91..0a670cd2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_framework -version: 1.0.0-dev.13 +version: 1.0.0-dev.14 description: Core libraries for the Angel framework. author: Tobe O homepage: https://github.com/angel-dart/angel_framework diff --git a/test/services.dart b/test/services.dart index d40d82e2..160ab668 100644 --- a/test/services.dart +++ b/test/services.dart @@ -1,3 +1,4 @@ +import 'package:angel_framework/defs.dart'; import 'package:angel_framework/angel_framework.dart'; import 'package:http/http.dart' as http; import 'package:json_god/json_god.dart' as god;