diff --git a/lib/src/http/http.dart b/lib/src/http/http.dart index a1f09d06..88b47ee0 100644 --- a/lib/src/http/http.dart +++ b/lib/src/http/http.dart @@ -8,6 +8,7 @@ export 'package:angel_model/angel_model.dart'; export 'package:angel_route/angel_route.dart'; export 'package:body_parser/body_parser.dart' show FileUploadInfo; export 'angel_base.dart'; +export 'angel_http.dart'; export 'anonymous_service.dart'; export 'controller.dart'; export 'hooked_service.dart'; diff --git a/lib/src/http/server.dart b/lib/src/http/server.dart index 1316299f..c8ea6eb9 100644 --- a/lib/src/http/server.dart +++ b/lib/src/http/server.dart @@ -90,7 +90,8 @@ class Angel extends AngelBase { /// Use the serving methods in [AngelHttp] instead. @deprecated - ServerGenerator get serverGenerator => _http.serverGenerator; + ServerGenerator get serverGenerator => + (_http ??= new AngelHttp(this)).serverGenerator; /// Returns the parent instance of this application, if any. Angel get parent => _parent; @@ -157,7 +158,7 @@ class Angel extends AngelBase { /// Use the serving methods in [AngelHttp] instead. @deprecated - HttpServer httpServer; + HttpServer get httpServer => _http?.httpServer; /// Use the serving methods in [AngelHttp] instead. @deprecated @@ -221,8 +222,8 @@ class Angel extends AngelBase { shutdownHooks.clear(); responseFinalizers.clear(); _flattened = null; - await _http.close(); - return _http.httpServer; + await _http?.close(); + return _http?.httpServer; } @override @@ -321,14 +322,18 @@ class Angel extends AngelBase { /// Use the serving methods in [AngelHttp] instead. @deprecated Future createRequestContext(HttpRequest request) { + _http ??= new AngelHttp(this); return _http.createRequestContext(request); } /// Use the serving methods in [AngelHttp] instead. @deprecated Future createResponseContext(HttpResponse response, - [RequestContext correspondingRequest]) => - _http.createResponseContext(response, correspondingRequest); + [RequestContext correspondingRequest]) { + _http ??= new AngelHttp(this); + + return _http.createResponseContext(response, correspondingRequest); + } /// Attempts to find a middleware by the given name within this application. findMiddleware(key) { @@ -347,6 +352,7 @@ class Angel extends AngelBase { Future handleAngelHttpException(AngelHttpException e, StackTrace st, RequestContext req, ResponseContext res, HttpRequest request, {bool ignoreFinalizers: false}) { + _http ??= new AngelHttp(this); return _http.handleAngelHttpException(e, st, req, res, request, ignoreFinalizers: ignoreFinalizers == true); } @@ -354,6 +360,7 @@ class Angel extends AngelBase { /// Use the serving methods in [AngelHttp] instead. @deprecated Future handleRequest(HttpRequest request) { + _http ??= new AngelHttp(this); return _http.handleRequest(request); } @@ -416,6 +423,7 @@ class Angel extends AngelBase { Future sendResponse( HttpRequest request, RequestContext req, ResponseContext res, {bool ignoreFinalizers: false}) { + _http ??= new AngelHttp(this); return _http.sendResponse(request, req, res); } @@ -501,7 +509,8 @@ class Angel extends AngelBase { /// Use the serving methods in [AngelHttp] instead. @deprecated - factory Angel.custom(Future Function(dynamic, int) serverGenerator) { + factory Angel.custom( + Future Function(dynamic, int) serverGenerator) { var app = new Angel(); return app.._http = new AngelHttp.custom(app, serverGenerator); } diff --git a/test/accepts_test.dart b/test/accepts_test.dart index d6c811cb..0c93b6a9 100644 --- a/test/accepts_test.dart +++ b/test/accepts_test.dart @@ -60,5 +60,6 @@ Future acceptContentTypes( rq.headers.set(HttpHeaders.ACCEPT, headerString); rq.close(); var app = new Angel(); - return app.createRequestContext(rq); + var http = new AngelHttp(app); + return http.createRequestContext(rq); } diff --git a/test/encoders_buffer_test.dart b/test/encoders_buffer_test.dart index 5879a19b..98bc70ee 100644 --- a/test/encoders_buffer_test.dart +++ b/test/encoders_buffer_test.dart @@ -29,15 +29,17 @@ main() { void encodingTests(Angel getApp()) { group('encoding', () { Angel app; + AngelHttp http; setUp(() { app = getApp(); + http = new AngelHttp(app); }); test('sends plaintext if no accept-encoding', () async { var rq = new MockHttpRequest('GET', Uri.parse('/hello'))..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rs.transform(UTF8.decoder).join(); expect(body, 'Hello, world!'); @@ -48,7 +50,7 @@ void encodingTests(Angel getApp()) { ..headers.set(HttpHeaders.ACCEPT_ENCODING, '*') ..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rs.fold>([], (out, list) => []..addAll(list)); expect(rs.headers.value(HttpHeaders.CONTENT_ENCODING), 'deflate'); @@ -60,7 +62,7 @@ void encodingTests(Angel getApp()) { ..headers.set(HttpHeaders.ACCEPT_ENCODING, ['foo', 'bar', '*']) ..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rs.fold>([], (out, list) => []..addAll(list)); expect(rs.headers.value(HttpHeaders.CONTENT_ENCODING), 'deflate'); @@ -72,7 +74,7 @@ void encodingTests(Angel getApp()) { ..headers.set(HttpHeaders.ACCEPT_ENCODING, 'gzip') ..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rs.fold>([], (out, list) => []..addAll(list)); expect(rs.headers.value(HttpHeaders.CONTENT_ENCODING), 'gzip'); @@ -84,7 +86,7 @@ void encodingTests(Angel getApp()) { ..headers.set(HttpHeaders.ACCEPT_ENCODING, ['gzip', 'deflate']) ..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rs.fold>([], (out, list) => []..addAll(list)); expect(rs.headers.value(HttpHeaders.CONTENT_ENCODING), 'gzip'); diff --git a/test/extension_test.dart b/test/extension_test.dart index c10603ec..34a5f37f 100644 --- a/test/extension_test.dart +++ b/test/extension_test.dart @@ -25,5 +25,6 @@ main() { Future makeRequest(String path) { var rq = new MockHttpRequest('GET', ENDPOINT.replace(path: path))..close(); var app = new Angel(); - return app.createRequestContext(rq); + var http = new AngelHttp(app); + return http.createRequestContext(rq); } diff --git a/test/parameter_meta_test.dart b/test/parameter_meta_test.dart index aa6009de..e72abcb3 100644 --- a/test/parameter_meta_test.dart +++ b/test/parameter_meta_test.dart @@ -17,9 +17,11 @@ Future printResponse(MockHttpResponse rs) { main() { Angel app; + AngelHttp http; setUp(() { app = new Angel()..lazyParseBodies = true; + http = new AngelHttp(app); app.get('/cookie', (@CookieValue('token') String jwt) { return jwt; @@ -61,7 +63,7 @@ main() { // Invalid request var rq = new MockHttpRequest('GET', Uri.parse('/header'))..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); await printResponse(rs); expect(rs.statusCode, 400); @@ -71,7 +73,7 @@ main() { ..headers.add('x-foo', 'bar') ..close(); rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await readResponse(rs); print('Body: $body'); @@ -83,7 +85,7 @@ main() { // Invalid request var rq = new MockHttpRequest('GET', Uri.parse('/session'))..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); await printResponse(rs); expect(rs.statusCode, 500); @@ -92,7 +94,7 @@ main() { rq.session['foo'] = 'bar'; rq.close(); rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); await printResponse(rs); expect(rs.statusCode, 200); @@ -105,7 +107,7 @@ main() { test('pattern matching', () async { var rq = new MockHttpRequest('GET', Uri.parse('/match?mode=pos'))..close(); var rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); @@ -113,7 +115,7 @@ main() { rq = new MockHttpRequest('GET', Uri.parse('/match?mode=neg'))..close(); rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); @@ -122,7 +124,7 @@ main() { // Fallback rq = new MockHttpRequest('GET', Uri.parse('/match?mode=ambi'))..close(); rs = rq.response; - await app.handleRequest(rq); + await http.handleRequest(rq); body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); diff --git a/test/primitives_test.dart b/test/primitives_test.dart index d7e55b3a..b53d04ef 100644 --- a/test/primitives_test.dart +++ b/test/primitives_test.dart @@ -6,9 +6,11 @@ import 'package:test/test.dart'; main() { Angel app; + AngelHttp http; setUp(() { app = new Angel()..inject('global', 305); // Pitbull! + http = new AngelHttp(app); app.get('/string/:string', (String string) => string); @@ -33,21 +35,21 @@ main() { test('String type annotation', () async { var rq = new MockHttpRequest('GET', Uri.parse('/string/hello'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var rs = await rq.response.transform(UTF8.decoder).join(); expect(rs, JSON.encode('hello')); }); test('Primitive after parsed param injection', () async { var rq = new MockHttpRequest('GET', Uri.parse('/num/parsed/24'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var rs = await rq.response.transform(UTF8.decoder).join(); expect(rs, JSON.encode(24)); }); test('globally-injected primitive', () async { var rq = new MockHttpRequest('GET', Uri.parse('/num/global'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var rs = await rq.response.transform(UTF8.decoder).join(); expect(rs, JSON.encode(305)); }); @@ -56,8 +58,8 @@ main() { try { var rq = new MockHttpRequest('GET', Uri.parse('/num/unparsed/32')) ..close(); - var req = await app.createRequestContext(rq); - var res = await app.createResponseContext(rq.response, req); + var req = await http.createRequestContext(rq); + var res = await http.createResponseContext(rq.response, req); await app.runContained((num unparsed) => unparsed, req, res); throw new StateError( 'ArgumentError should be thrown if a parameter cannot be resolved.'); diff --git a/test/routing_test.dart b/test/routing_test.dart index 02fb3b13..004bdaf7 100644 --- a/test/routing_test.dart +++ b/test/routing_test.dart @@ -100,7 +100,7 @@ main() { }); tearDown(() async { - await app.httpServer.close(force: true); + await app.close(); app = null; nested = null; todos = null; diff --git a/test/server_test.dart b/test/server_test.dart index c22337b1..f952b467 100644 --- a/test/server_test.dart +++ b/test/server_test.dart @@ -29,23 +29,27 @@ main() { }); test('custom server generator', () { - var app = new Angel.custom(HttpServer.bind); - expect(app.serverGenerator, HttpServer.bind); + var app = new Angel(); + var http = new AngelHttp.custom(app, HttpServer.bind); + expect(http.serverGenerator, HttpServer.bind); }); test('default error handler', () async { var app = new Angel(); + var http = new AngelHttp(app); var rq = new MockHttpRequest('GET', $foo); rq.close(); var rs = rq.response; - var req = await app.createRequestContext(rq); - var res = await app.createResponseContext(rs); + var req = await http.createRequestContext(rq); + var res = await http.createResponseContext(rs); var e = new AngelHttpException(null, statusCode: 321, message: 'Hello', errors: ['foo', 'bar']); await app.errorHandler(e, req, res); - await app.sendResponse(rq, req, res); - expect(rs.headers.value(HttpHeaders.CONTENT_TYPE), - ContentType.HTML.toString()); + await http.sendResponse(rq, req, res); + expect( + ContentType.parse(rs.headers.value(HttpHeaders.CONTENT_TYPE)).mimeType, + ContentType.HTML.mimeType, + ); expect(rs.statusCode, e.statusCode); var body = await rs.transform(UTF8.decoder).join(); expect(body, contains('${e.message}')); @@ -81,24 +85,27 @@ main() { test('global injection added to injection map', () async { var app = new Angel()..inject('a', 'b'); + var http = new AngelHttp(app); app.get('/', (String a) => a); var rq = new MockHttpRequest('GET', Uri.parse('/'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rq.response.transform(UTF8.decoder).join(); expect(body, JSON.encode('b')); }); test('global injected serializer', () async { - var app = new Angel()..injectSerializer((_) => 'x'); + var app = new Angel()..serializer = (_) => 'x'; + var http = new AngelHttp(app); app.get($foo.path, (req, ResponseContext res) => res.serialize(null)); var rq = new MockHttpRequest('GET', $foo)..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rq.response.transform(UTF8.decoder).join(); expect(body, 'x'); }); group('handler results', () { var app = new Angel(); + var http = new AngelHttp(app); app.responseFinalizers .add((req, res) => throw new AngelHttpException.forbidden()); RequestContext req; @@ -106,8 +113,8 @@ main() { setUp(() async { var rq = new MockHttpRequest('GET', $foo)..close(); - req = await app.createRequestContext(rq); - res = await app.createResponseContext(rq.response); + req = await http.createRequestContext(rq); + res = await http.createResponseContext(rq.response); }); group('getHandlerResult', () { @@ -140,12 +147,14 @@ main() { group('handleAngelHttpException', () { Angel app; + AngelHttp http; setUp(() async { app = new Angel(); app.get('/wtf', () => throw new AngelHttpException.forbidden()); app.get('/wtf2', () => throw new AngelHttpException.forbidden()); - await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0); + http = new AngelHttp(app); + await http.startServer(InternetAddress.LOOPBACK_IP_V4, 0); var oldHandler = app.errorHandler; app.errorHandler = (e, req, res) { @@ -161,7 +170,7 @@ main() { var rq = new MockHttpRequest('GET', new Uri(path: 'wtf')) ..headers.set(HttpHeaders.ACCEPT, ContentType.JSON.toString()); rq.close(); - await app.handleRequest(rq); + await http.handleRequest(rq); expect(rq.response.statusCode, HttpStatus.FORBIDDEN); expect( rq.response.headers.contentType.mimeType, ContentType.JSON.mimeType); @@ -171,7 +180,7 @@ main() { var rq = new MockHttpRequest('GET', new Uri(path: 'wtf')) ..headers.set(HttpHeaders.ACCEPT, ContentType.JSON.toString()); rq.close(); - await app.handleRequest(rq); + await http.handleRequest(rq); expect(rq.response.statusCode, HttpStatus.FORBIDDEN); expect( rq.response.headers.contentType.mimeType, ContentType.JSON.mimeType); @@ -181,7 +190,7 @@ main() { var rq = new MockHttpRequest('GET', new Uri(path: 'wtf2')); rq.headers.set(HttpHeaders.ACCEPT, ContentType.HTML.toString()); rq.close(); - await app.handleRequest(rq); + await http.handleRequest(rq); expect(rq.response.statusCode, HttpStatus.FORBIDDEN); expect( rq.response.headers.contentType?.mimeType, ContentType.HTML.mimeType); diff --git a/test/streaming_test.dart b/test/streaming_test.dart index 3ecf71d2..e2e9e489 100644 --- a/test/streaming_test.dart +++ b/test/streaming_test.dart @@ -9,9 +9,11 @@ import 'encoders_buffer_test.dart' show encodingTests; main() { Angel app; + AngelHttp http; setUp(() { app = new Angel(); + http = new AngelHttp(app); app.logger = new Logger('streaming_test') ..onRecord.listen((rec) { @@ -66,11 +68,11 @@ main() { }; }); - tearDown(() => app.close()); + tearDown(() => http.close()); _expectHelloBye(String path) async { var rq = new MockHttpRequest('GET', Uri.parse(path))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rq.response.transform(UTF8.decoder).join(); expect(body, 'Hello, world!bye'); } @@ -81,7 +83,7 @@ main() { test('cannot write after close', () async { var rq = new MockHttpRequest('GET', Uri.parse('/overwrite'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rq.response.transform(UTF8.decoder).join(); if (rq.response.statusCode != 32) @@ -91,7 +93,7 @@ main() { test('res => addError', () async { try { var rq = new MockHttpRequest('GET', Uri.parse('/error'))..close(); - await app.handleRequest(rq); + await http.handleRequest(rq); var body = await rq.response.transform(UTF8.decoder).join(); throw 'addError should throw error; response: $body'; } on StateError {