diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3127f8de..c7b6016a 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,13 +2,9 @@ - - - - @@ -35,8 +31,8 @@ - - + + @@ -45,60 +41,35 @@ - - + + - - - - + - + - - - - - - - - - - - - + + - - - - - - - - - - - - @@ -143,7 +114,17 @@ throw upa transform + isAfter + isBefore + close + !_isOpen + end + reopen + REDIRECT + + _isClosed + - @@ -316,6 +297,9 @@ + + + @@ -338,6 +322,12 @@ + + @@ -401,7 +391,8 @@ - + + 1481237183504 @@ -445,13 +436,17 @@ - - - - @@ -461,6 +456,9 @@ + + + @@ -481,7 +479,7 @@ - @@ -493,23 +491,23 @@ - + + - - - - - + + - + + + @@ -531,7 +529,8 @@ - @@ -542,9 +541,6 @@ - - - @@ -626,7 +622,6 @@ - @@ -634,7 +629,6 @@ - @@ -701,7 +695,6 @@ - @@ -709,7 +702,6 @@ - @@ -823,9 +815,6 @@ - - - @@ -833,7 +822,6 @@ - @@ -841,7 +829,6 @@ - @@ -849,7 +836,6 @@ - @@ -871,6 +857,14 @@ + + + + + + + + @@ -881,71 +875,39 @@ - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - + + + + + + + + + + + + + @@ -957,5 +919,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index c605acd2..bbc09c1a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # angel_framework -[![pub 1.0.1](https://img.shields.io/badge/pub-1.0.1-brightgreen.svg)](https://pub.dartlang.org/packages/angel_framework) +[![pub 1.0.2](https://img.shields.io/badge/pub-1.0.2-brightgreen.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) A high-powered HTTP server with support for dependency injection, sophisticated routing and more. diff --git a/lib/hooks.dart b/lib/hooks.dart index 71aa40d2..510b6731 100644 --- a/lib/hooks.dart +++ b/lib/hooks.dart @@ -241,7 +241,7 @@ HookedServiceEventListener addCreatedAt({ } } - var now = new DateTime.now().toIso8601String(); + var now = new DateTime.now().toUtc().toIso8601String(); normalize(obj) async { if (obj != null) { @@ -292,7 +292,7 @@ HookedServiceEventListener addUpdatedAt({ } } - var now = new DateTime.now().toIso8601String(); + var now = new DateTime.now().toUtc().toIso8601String(); normalize(obj) async { if (obj != null) { diff --git a/lib/src/http/response_context.dart b/lib/src/http/response_context.dart index 01b2efdc..668a9805 100644 --- a/lib/src/http/response_context.dart +++ b/lib/src/http/response_context.dart @@ -22,7 +22,7 @@ typedef String ResponseSerializer(data); class ResponseContext extends Extensible { final _LockableBytesBuilder _buffer = new _LockableBytesBuilder(); final Map _headers = {HttpHeaders.SERVER: 'angel'}; - bool _isOpen = true; + bool _isOpen = true, _isClosed = false; /// The [Angel] instance that is sending a response. Angel app; @@ -36,10 +36,10 @@ class ResponseContext extends Extensible { /// Headers that will be sent to the user. Map get headers { /// If the response is closed, then this getter will return an immutable `Map`. - /*if (!_isOpen) + if (!_isOpen) return new Map.unmodifiable(_headers); - else*/ - return _headers; + else + return _headers; } /// Serializes response data into a String. @@ -112,7 +112,7 @@ class ResponseContext extends Extensible { /// Sends a download as a response. download(File file, {String filename}) async { - // if (!_isOpen) throw _closed(); + if (!_isOpen) throw _closed(); headers["Content-Disposition"] = 'attachment; filename="${filename ?? file.path}"'; @@ -122,15 +122,25 @@ class ResponseContext extends Extensible { end(); } - /// Prevents more data from being written to the response. - void end() { + /// Prevents more data from being written to the response, and locks it entire from further editing. + void close() { _buffer._lock(); _isOpen = false; + _isClosed = true; + } + + /// Prevents further request handlers from running on the response, except for response finalizers. + /// + /// To disable response finalizers, see [willCloseItself]. + void end() { + _isOpen = false; } /// Re-opens a closed response. **NEVER USE THIS IN A PLUGIN**. /// /// To preserve your sanity, don't use it ever. This is solely for internal use. + /// + /// You're going to need this one day, and you'll be happy it was added. void reopen() { _buffer._reopen(); _isOpen = true; @@ -150,7 +160,7 @@ class ResponseContext extends Extensible { /// Returns a JSONP response. void jsonp(value, {String callbackName: "callback", contentType}) { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); write("$callbackName(${serializer(value)})"); if (contentType != null) { @@ -166,7 +176,7 @@ class ResponseContext extends Extensible { /// Renders a view to the response stream, and closes the response. Future render(String view, [Map data]) async { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); write(await app.viewGenerator(view, data)); headers[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString(); end(); @@ -180,7 +190,7 @@ class ResponseContext extends Extensible { /// /// See [Router]#navigate for more. :) void redirect(url, {bool absolute: true, int code: 302}) { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); headers ..[HttpHeaders.CONTENT_TYPE] = ContentType.HTML.toString() ..[HttpHeaders.LOCATION] = @@ -208,7 +218,7 @@ class ResponseContext extends Extensible { /// Redirects to the given named [Route]. void redirectTo(String name, [Map params, int code]) { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); Route _findRoute(Router r) { for (Route route in r.routes) { if (route is SymlinkRoute) { @@ -233,7 +243,7 @@ class ResponseContext extends Extensible { /// Redirects to the given [Controller] action. void redirectToAction(String action, [Map params, int code]) { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); // UserController@show List split = action.split("@"); @@ -263,7 +273,7 @@ class ResponseContext extends Extensible { /// Copies a file's contents into the response buffer. Future sendFile(File file, {int chunkSize, int sleepMs: 0, bool resumable: true}) async { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path); buffer.add(await file.readAsBytes()); @@ -274,7 +284,7 @@ class ResponseContext extends Extensible { /// /// [contentType] can be either a [String], or a [ContentType]. void serialize(value, {contentType}) { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); var text = serializer(value); write(text); @@ -293,13 +303,13 @@ class ResponseContext extends Extensible { int sleepMs: 0, bool resumable: true, Codec, List> codec}) async { - // if (!_isOpen) throw _closed(); + if (_isClosed) throw _closed(); headers[HttpHeaders.CONTENT_TYPE] = lookupMimeType(file.path); end(); willCloseItself = true; - var stream = codec != null + Stream stream = codec != null ? file.openRead().transform(codec.encoder) : file.openRead(); await stream.pipe(io); @@ -307,14 +317,14 @@ class ResponseContext extends Extensible { /// Writes data to the response. void write(value, {Encoding encoding: UTF8}) { - /*if (!_isOpen) + if (_isClosed) throw _closed(); - else {*/ - if (value is List) - buffer.add(value); - else - buffer.add(encoding.encode(value.toString())); - //} + else { + if (value is List) + buffer.add(value); + else + buffer.add(encoding.encode(value.toString())); + } } } @@ -333,7 +343,7 @@ class _LockableBytesBuilderImpl implements _LockableBytesBuilder { @override void _lock() { - // _closed = true; + _closed = true; } @override diff --git a/lib/src/http/server.dart b/lib/src/http/server.dart index f32fe3a9..b52a2bef 100644 --- a/lib/src/http/server.dart +++ b/lib/src/http/server.dart @@ -476,8 +476,6 @@ class Angel extends AngelBase { _afterProcessed.add(request); if (!res.willCloseItself) { - res.reopen(); - for (var finalizer in responseFinalizers) { await finalizer(req, res); } diff --git a/pubspec.yaml b/pubspec.yaml index a1990838..32df2ec1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_framework -version: 1.0.1 +version: 1.0.2 description: A high-powered HTTP server with DI, routing and more. author: Tobe O homepage: https://github.com/angel-dart/angel_framework