diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 7b016146..aa5d08f2 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,8 +3,12 @@ + + + + @@ -27,35 +31,65 @@ - - - - - - - - + + + + + + + + - - + + - - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -63,6 +97,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -75,12 +133,8 @@ - reflector - Angel(M - pool super close() - close( DEFUNC const dart2_constant/convert.dart @@ -105,9 +159,12 @@ injecti debug handle( + lock + add( + close( + end() - 'server' FutureOr var body = await getBody(rs); @@ -137,6 +194,7 @@ )); req req.container + close() C:\Users\thosa\Source\Angel\framework\lib @@ -202,15 +260,15 @@ @@ -247,6 +305,11 @@ + + + + + @@ -313,7 +376,7 @@ - + @@ -994,7 +1057,7 @@ - @@ -1030,7 +1093,7 @@ - + @@ -1057,8 +1120,6 @@ @@ -1245,16 +1308,6 @@ - - - - - - - - - - @@ -1290,16 +1343,6 @@ - - - - - - - - - - @@ -1320,16 +1363,6 @@ - - - - - - - - - - @@ -1337,13 +1370,6 @@ - - - - - - - @@ -1351,16 +1377,6 @@ - - - - - - - - - - @@ -1382,16 +1398,6 @@ - - - - - - - - - - @@ -1431,10 +1437,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1444,33 +1521,13 @@ - - + + - - - - - - - - - - - - - - - - - - - - diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f6ad30..d5982410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,4 +59,6 @@ as in many cases it is unnecessary and slows down response time. * `ResponseContext.streaming` was replaced by `ResponseContext.isBuffered`. * Made `LockableBytesBuilder` public. * Removed the now-obsolete `ResponseContext.willCloseItself`. -* Removed `ResponseContext.dispose`. \ No newline at end of file +* Removed `ResponseContext.dispose`. +* Removed the now-obsolete `ResponseContext.end`. +* Removed the now-obsolete `ResponseContext.releaseCorrespondingRequest`. \ No newline at end of file diff --git a/lib/src/core/response_context.dart b/lib/src/core/response_context.dart index 533cdf98..0964db40 100644 --- a/lib/src/core/response_context.dart +++ b/lib/src/core/response_context.dart @@ -110,7 +110,7 @@ abstract class ResponseContext file.openRead().pipe(this); } else { buffer.add(file.readAsBytesSync()); - end(); + close(); } } @@ -126,15 +126,6 @@ abstract class ResponseContext return new Future.value(); } - /// Prevents further request handlers from running on the response, except for response finalizers. - /// - /// To disable response finalizers, see [willCloseItself]. - /// - /// This method should also set [!isOpen] to true. - void end() { - if (_done?.isCompleted == false) _done.complete(); - } - /// Serializes JSON to the response. void json(value) => this ..contentType = MediaType('application', 'json') @@ -148,7 +139,7 @@ abstract class ResponseContext write("$callbackName(${serializer(value)})"); this.contentType = contentType ?? new MediaType('application', 'javascript'); - end(); + close(); } /// Renders a view to the response stream, and closes the response. @@ -160,7 +151,7 @@ abstract class ResponseContext ..addAll(data ?? {}))).then((content) { write(content); headers['content-type'] = 'text/html'; - end(); + close(); }); } @@ -196,7 +187,7 @@ abstract class ResponseContext '''); - end(); + close(); } /// Redirects to the given named [Route]. @@ -267,7 +258,7 @@ abstract class ResponseContext headers['content-type'] = lookupMimeType(file.path); buffer.add(file.readAsBytesSync()); - end(); + close(); } /// Serializes data to the response. @@ -276,7 +267,7 @@ abstract class ResponseContext var text = serializer(value); if (text.isEmpty) return true; write(text); - end(); + close(); return false; } @@ -287,14 +278,6 @@ abstract class ResponseContext return file.openRead().pipe(this); } - /// Releases critical resources from the [correspondingRequest]. - void releaseCorrespondingRequest() { - if (!correspondingRequest.app.isProduction && - correspondingRequest.app.logger != null) { - correspondingRequest.container.make().stop(); - } - } - /// Configure the response to write to an intermediate response buffer, rather than to the stream directly. void enableBuffer(); diff --git a/lib/src/core/server.dart b/lib/src/core/server.dart index 08c600b2..42c5535f 100644 --- a/lib/src/core/server.dart +++ b/lib/src/core/server.dart @@ -151,7 +151,7 @@ class Angel extends Routable { } res.write(""); - res.end(); + res.close(); }; @override diff --git a/lib/src/http/angel_http.dart b/lib/src/http/angel_http.dart index 09ed2485..4c3e4e29 100644 --- a/lib/src/http/angel_http.dart +++ b/lib/src/http/angel_http.dart @@ -273,7 +273,7 @@ class AngelHttp { res.statusCode = e.statusCode; handleError = new Future.sync(() => app.errorHandler(e, req, res)).then((result) { - return app.executeHandler(result, req, res).then((_) => res.end()); + return app.executeHandler(result, req, res).then((_) => res.close()); }); } @@ -285,7 +285,15 @@ class AngelHttp { Future sendResponse( HttpRequest request, RequestContext req, ResponseContext res, {bool ignoreFinalizers: false}) { - if (!res.isBuffered) return new Future.value(); + void _cleanup(_) { + if (!app.isProduction && app.logger != null) { + var sw = req.container.make(); + app.logger.info( + "${res.statusCode} ${req.method} ${req.uri} (${sw?.elapsedMilliseconds ?? 'unknown'} ms)"); + } + } + + if (!res.isBuffered) return res.close().then(_cleanup); Future finalizers = ignoreFinalizers == true ? new Future.value() @@ -293,7 +301,7 @@ class AngelHttp { new Future.value(), (out, f) => out.then((_) => f(req, res))); return finalizers.then((_) { - if (res.isOpen) res.end(); + if (res.isOpen) res.close(); for (var key in res.headers.keys) { request.response.headers.add(key, res.headers[key]); @@ -343,17 +351,7 @@ class AngelHttp { ..cookies.addAll(res.cookies) ..add(outputBuffer); - return request.response.close().then((_) { - if (!app.isProduction && app.logger != null) { - var sw = req.container.make(); - - if (sw.isRunning) { - sw?.stop(); - app.logger.info( - "${res.statusCode} ${req.method} ${req.uri} (${sw?.elapsedMilliseconds ?? 'unknown'} ms)"); - } - } - }); + return request.response.close().then(_cleanup); }); } diff --git a/lib/src/http/http_response_context.dart b/lib/src/http/http_response_context.dart index 06074b56..c2e263c5 100644 --- a/lib/src/http/http_response_context.dart +++ b/lib/src/http/http_response_context.dart @@ -5,6 +5,7 @@ import 'dart:io'; import '../core/core.dart'; import 'http_request_context.dart'; +/// An implementation of [ResponseContext] that abstracts over an [HttpResponse]. class HttpResponseContext extends ResponseContext { /// The underlying [HttpResponse] under this instance. @override @@ -53,21 +54,13 @@ class HttpResponseContext extends ResponseContext { ..statusCode = statusCode ..cookies.addAll(cookies); headers.forEach(rawResponse.headers.set); - _isClosed = true; - releaseCorrespondingRequest(); + //_isClosed = true; return _streamInitialized = true; } return false; } - @override - void end() { - _buffer?.lock(); - _isClosed = true; - super.end(); - } - @override Future addStream(Stream> stream) { if (_isClosed && isBuffered) throw ResponseContext.closed(); @@ -127,16 +120,21 @@ class HttpResponseContext extends ResponseContext { @override Future close() { - if (!isBuffered) { - try { - rawResponse.close(); - } catch (_) { - // This only seems to occur on `MockHttpRequest`, but - // this try/catch prevents a crash. + if (!_isClosed) { + if (!isBuffered) { + try { + rawResponse.close(); + } catch (_) { + // This only seems to occur on `MockHttpRequest`, but + // this try/catch prevents a crash. + } + } else { + _buffer.lock(); } + + _isClosed = true; } - _isClosed = true; super.close(); return new Future.value(); } diff --git a/test/routing_test.dart b/test/routing_test.dart index 05fcf9fa..3edb1f46 100644 --- a/test/routing_test.dart +++ b/test/routing_test.dart @@ -25,7 +25,7 @@ class QueryService extends Service { void interceptor(RequestContext req, ResponseContext res) { res ..write('Middleware') - ..end(); + ..close(); } void interceptService(RequestContext req, ResponseContext res) {