diff --git a/.travis.yml b/.travis.yml index e7c5d2f..0cb4849 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,12 +6,14 @@ dart: dart_task: - test - - dartanalyzer: --fatal-infos --fatal-warnings . matrix: include: - - dart: dev - dart_task: dartfmt + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: + dartanalyzer: --fatal-infos --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: diff --git a/test/http_body_test.dart b/test/http_body_test.dart index b9318f4..e450623 100644 --- a/test/http_body_test.dart +++ b/test/http_body_test.dart @@ -9,149 +9,145 @@ import 'package:http_server/http_server.dart'; import 'package:test/test.dart'; void _testHttpClientResponseBody() { - void test( + void check( String mimeType, List content, dynamic expectedBody, String type, - [bool shouldFail = false]) { - HttpServer.bind('localhost', 0).then((server) { - server.listen((request) { - request.listen((_) {}, onDone: () { - request.response.headers.contentType = ContentType.parse(mimeType); - request.response.add(content); - request.response.close(); - }); - }); - - var client = HttpClient(); - client - .get('localhost', server.port, '/') - .then((request) => request.close()) - .then(HttpBodyHandler.processResponse) - .then((body) { - expect(shouldFail, isFalse); - expect(body.type, equals(type)); - expect(body.response, isNotNull); - switch (type) { - case 'text': - case 'json': - expect(body.body, equals(expectedBody)); - break; - - default: - fail('bad body type'); - } - }, onError: (error) { - if (!shouldFail) throw error; - }).whenComplete(() async { - client.close(); - await server.close(); + [bool shouldFail = false]) async { + var server = await HttpServer.bind('localhost', 0); + server.listen((request) { + request.listen((_) {}, onDone: () { + request.response.headers.contentType = ContentType.parse(mimeType); + request.response.add(content); + request.response.close(); }); }); + + var client = HttpClient(); + try { + var request = await client.get('localhost', server.port, '/'); + var response = await request.close(); + var body = await HttpBodyHandler.processResponse(response); + expect(shouldFail, isFalse); + expect(body.type, equals(type)); + expect(body.response, isNotNull); + switch (type) { + case 'text': + case 'json': + expect(body.body, equals(expectedBody)); + break; + + default: + fail('bad body type'); + } + } catch (_) { + if (!shouldFail) rethrow; + } finally { + client.close(); + await server.close(); + } } - test('text/plain', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=utf-8', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=iso-8859-1', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=us-ascii', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=utf-8', [42], '*', 'text'); - test('text/plain; charset=us-ascii', [142], null, 'text', true); - test('text/plain; charset=utf-8', [142], null, 'text', true); + check('text/plain', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=utf-8', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=iso-8859-1', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=us-ascii', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=utf-8', [42], '*', 'text'); + check('text/plain; charset=us-ascii', [142], null, 'text', true); + check('text/plain; charset=utf-8', [142], null, 'text', true); - test('application/json', '{"val": 5}'.codeUnits, {'val': 5}, 'json'); - test('application/json', '{ bad json }'.codeUnits, null, 'json', true); + check('application/json', '{"val": 5}'.codeUnits, {'val': 5}, 'json'); + check('application/json', '{ bad json }'.codeUnits, null, 'json', true); } void _testHttpServerRequestBody() { - void test( + void check( String mimeType, List content, dynamic expectedBody, String type, - {bool shouldFail = false, Encoding defaultEncoding = utf8}) { - HttpServer.bind('localhost', 0).then((server) { - server - .transform(HttpBodyHandler(defaultEncoding: defaultEncoding)) - .listen((body) { - if (shouldFail) return; - expect(shouldFail, isFalse); - expect(body.type, equals(type)); - switch (type) { - case 'text': - expect(body.request.headers.contentType.mimeType, - equals('text/plain')); - expect(body.body, equals(expectedBody)); - break; - - case 'json': - expect(body.request.headers.contentType.mimeType, - equals('application/json')); - expect(body.body, equals(expectedBody)); - break; - - case 'binary': - expect(body.request.headers.contentType, isNull); - expect(body.body, equals(expectedBody)); - break; - - case 'form': - var mimeType = body.request.headers.contentType.mimeType; - expect( - mimeType, - anyOf(equals('multipart/form-data'), - equals('application/x-www-form-urlencoded'))); - expect(body.body.keys.toSet(), equals(expectedBody.keys.toSet())); - for (var key in expectedBody.keys) { - var found = body.body[key]; - var expected = expectedBody[key]; - if (found is HttpBodyFileUpload) { - expect(found.contentType.toString(), - equals(expected['contentType'])); - expect(found.filename, equals(expected['filename'])); - expect(found.content, equals(expected['content'])); - } else { - expect(found, equals(expected)); - } + {bool shouldFail = false, Encoding defaultEncoding = utf8}) async { + var server = await HttpServer.bind('localhost', 0); + server.transform(HttpBodyHandler(defaultEncoding: defaultEncoding)).listen( + (body) { + if (shouldFail) return; + expect(shouldFail, isFalse); + expect(body.type, equals(type)); + switch (type) { + case 'text': + expect( + body.request.headers.contentType.mimeType, equals('text/plain')); + expect(body.body, equals(expectedBody)); + break; + + case 'json': + expect(body.request.headers.contentType.mimeType, + equals('application/json')); + expect(body.body, equals(expectedBody)); + break; + + case 'binary': + expect(body.request.headers.contentType, isNull); + expect(body.body, equals(expectedBody)); + break; + + case 'form': + var mimeType = body.request.headers.contentType.mimeType; + expect( + mimeType, + anyOf(equals('multipart/form-data'), + equals('application/x-www-form-urlencoded'))); + expect(body.body.keys.toSet(), equals(expectedBody.keys.toSet())); + for (var key in expectedBody.keys) { + var found = body.body[key]; + var expected = expectedBody[key]; + if (found is HttpBodyFileUpload) { + expect(found.contentType.toString(), + equals(expected['contentType'])); + expect(found.filename, equals(expected['filename'])); + expect(found.content, equals(expected['content'])); + } else { + expect(found, equals(expected)); } - break; - - default: - throw StateError('bad body type'); - } - body.request.response.close(); - }, onError: (error) { - if (!shouldFail) throw error; - }); - - var client = HttpClient(); - client.post('localhost', server.port, '/').then((request) { - if (mimeType != null) { - request.headers.contentType = ContentType.parse(mimeType); - } - request.add(content); - return request.close(); - }).then((response) { - if (shouldFail) { - expect(response.statusCode, equals(HttpStatus.badRequest)); - } - return response.drain(); - }).whenComplete(() async { - client.close(); - await server.close(); - }).catchError((e) { - if (!shouldFail) throw e; - }); + } + break; + + default: + throw StateError('bad body type'); + } + body.request.response.close(); + }, onError: (error) { + if (!shouldFail) throw error; }); + + var client = HttpClient(); + try { + var request = await client.post('localhost', server.port, '/'); + if (mimeType != null) { + request.headers.contentType = ContentType.parse(mimeType); + } + request.add(content); + var response = await request.close(); + if (shouldFail) { + expect(response.statusCode, equals(HttpStatus.badRequest)); + } + return response.drain(); + } catch (_) { + if (!shouldFail) rethrow; + } finally { + client.close(); + await server.close(); + } } - test('text/plain', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=utf-8', 'body'.codeUnits, 'body', 'text'); - test('text/plain; charset=utf-8', [42], '*', 'text'); - test('text/plain; charset=us-ascii', [142], null, 'text', shouldFail: true); - test('text/plain; charset=utf-8', [142], null, 'text', shouldFail: true); + check('text/plain', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=utf-8', 'body'.codeUnits, 'body', 'text'); + check('text/plain; charset=utf-8', [42], '*', 'text'); + check('text/plain; charset=us-ascii', [142], null, 'text', shouldFail: true); + check('text/plain; charset=utf-8', [142], null, 'text', shouldFail: true); - test('application/json', '{"val": 5}'.codeUnits, {'val': 5}, 'json'); - test('application/json', '{ bad json }'.codeUnits, null, 'json', + check('application/json', '{"val": 5}'.codeUnits, {'val': 5}, 'json'); + check('application/json', '{ bad json }'.codeUnits, null, 'json', shouldFail: true); - test(null, 'body'.codeUnits, 'body'.codeUnits, 'binary'); + check(null, 'body'.codeUnits, 'body'.codeUnits, 'binary'); - test( + check( 'multipart/form-data; boundary=AaB03x', ''' --AaB03x\r @@ -163,7 +159,7 @@ Larry\r {'name': 'Larry'}, 'form'); - test( + check( 'multipart/form-data; boundary=AaB03x', ''' --AaB03x\r @@ -182,7 +178,7 @@ File content\r }, 'form'); - test( + check( 'multipart/form-data; boundary=AaB03x', ''' --AaB03x\r @@ -206,7 +202,7 @@ File content\r }, 'form'); - test( + check( 'multipart/form-data; boundary=AaB03x', ''' --AaB03x\r @@ -225,7 +221,7 @@ File content\r }, 'form'); - test( + check( 'application/x-www-form-urlencoded', '%E5%B9%B3%3D%E4%BB%AE%E5%90%8D=%E5%B9%B3%E4%BB%AE%E5%90%8D&b' '=%E5%B9%B3%E4%BB%AE%E5%90%8D' @@ -233,58 +229,58 @@ File content\r {'平=仮名': '平仮名', 'b': '平仮名'}, 'form'); - test('application/x-www-form-urlencoded', 'a=%F8+%26%23548%3B'.codeUnits, + check('application/x-www-form-urlencoded', 'a=%F8+%26%23548%3B'.codeUnits, null, 'form', shouldFail: true); - test('application/x-www-form-urlencoded', 'a=%C0%A0'.codeUnits, null, 'form', + check('application/x-www-form-urlencoded', 'a=%C0%A0'.codeUnits, null, 'form', shouldFail: true); - test('application/x-www-form-urlencoded', 'a=x%A0x'.codeUnits, null, 'form', + check('application/x-www-form-urlencoded', 'a=x%A0x'.codeUnits, null, 'form', shouldFail: true); - test('application/x-www-form-urlencoded', 'a=x%C0x'.codeUnits, null, 'form', + check('application/x-www-form-urlencoded', 'a=x%C0x'.codeUnits, null, 'form', shouldFail: true); - test('application/x-www-form-urlencoded', 'a=%C3%B8+%C8%A4'.codeUnits, + check('application/x-www-form-urlencoded', 'a=%C3%B8+%C8%A4'.codeUnits, {'a': 'ø Ȥ'}, 'form'); - test('application/x-www-form-urlencoded', 'a=%F8+%26%23548%3B'.codeUnits, + check('application/x-www-form-urlencoded', 'a=%F8+%26%23548%3B'.codeUnits, {'a': 'ø Ȥ'}, 'form', defaultEncoding: latin1); - test('application/x-www-form-urlencoded', 'name=%26'.codeUnits, {'name': '&'}, - 'form', + check('application/x-www-form-urlencoded', 'name=%26'.codeUnits, + {'name': '&'}, 'form', defaultEncoding: latin1); - test('application/x-www-form-urlencoded', 'name=%F8%26'.codeUnits, + check('application/x-www-form-urlencoded', 'name=%F8%26'.codeUnits, {'name': 'ø&'}, 'form', defaultEncoding: latin1); - test('application/x-www-form-urlencoded', 'name=%26%3B'.codeUnits, + check('application/x-www-form-urlencoded', 'name=%26%3B'.codeUnits, {'name': '&;'}, 'form', defaultEncoding: latin1); - test( + check( 'application/x-www-form-urlencoded', 'name=%26%23548%3B%26%23548%3B'.codeUnits, {'name': 'ȤȤ'}, 'form', defaultEncoding: latin1); - test('application/x-www-form-urlencoded', 'name=%26'.codeUnits, {'name': '&'}, - 'form'); + check('application/x-www-form-urlencoded', 'name=%26'.codeUnits, + {'name': '&'}, 'form'); - test('application/x-www-form-urlencoded', 'name=%C3%B8%26'.codeUnits, + check('application/x-www-form-urlencoded', 'name=%C3%B8%26'.codeUnits, {'name': 'ø&'}, 'form'); - test('application/x-www-form-urlencoded', 'name=%26%3B'.codeUnits, + check('application/x-www-form-urlencoded', 'name=%26%3B'.codeUnits, {'name': '&;'}, 'form'); - test('application/x-www-form-urlencoded', 'name=%C8%A4%26%23548%3B'.codeUnits, - {'name': 'ȤȤ'}, 'form'); + check('application/x-www-form-urlencoded', + 'name=%C8%A4%26%23548%3B'.codeUnits, {'name': 'ȤȤ'}, 'form'); - test('application/x-www-form-urlencoded', 'name=%C8%A4%C8%A4'.codeUnits, + check('application/x-www-form-urlencoded', 'name=%C8%A4%C8%A4'.codeUnits, {'name': 'ȤȤ'}, 'form'); } diff --git a/test/http_multipart_test.dart b/test/http_multipart_test.dart index 6dfc8eb..d32039b 100644 --- a/test/http_multipart_test.dart +++ b/test/http_multipart_test.dart @@ -65,36 +65,30 @@ Future _postDataTest(List message, String contentType, String boundary, var server = await HttpServer.bind(addr, 0); - server.listen((request) { + server.listen((request) async { var boundary = request.headers.contentType.parameters['boundary']; - MimeMultipartTransformer(boundary) + var fields = await MimeMultipartTransformer(boundary) .bind(request) .map((part) => HttpMultipartFormData.parse(part, defaultEncoding: defaultEncoding)) - .map((multipart) { - Future future; - if (multipart.isText) { - future = multipart.join(); - } else { - future = multipart.fold([], (b, s) => b..addAll(s)); - } - return future.then((data) { - String contentType; - if (multipart.contentType != null) { - contentType = multipart.contentType.mimeType; - } - return FormField( - multipart.contentDisposition.parameters['name'], data, - contentType: contentType, - filename: multipart.contentDisposition.parameters['filename']); - }); - }) - .toList() - .then(Future.wait) - .then((fields) { - expect(fields, equals(expectedFields)); - request.response.close().then((_) => server.close()); - }); + .asyncMap((multipart) async { + dynamic data; + if (multipart.isText) { + data = await multipart.join(); + } else { + data = await multipart.fold([], (b, s) => b..addAll(s)); + } + String contentType; + if (multipart.contentType != null) { + contentType = multipart.contentType.mimeType; + } + return FormField(multipart.contentDisposition.parameters['name'], data, + contentType: contentType, + filename: multipart.contentDisposition.parameters['filename']); + }).toList(); + expect(fields, equals(expectedFields)); + await request.response.close(); + await server.close(); }); var client = HttpClient(); diff --git a/test/utils.dart b/test/utils.dart index 728b5fb..9be809b 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -54,7 +54,7 @@ Future statusCodeForVirtDir(VirtualDirectory virtualDir, String path, bool rawPath = false, bool followRedirects = true, int from, - int to}) { + int to}) async { // if this is a fake test, then run the fake code path if (_isFakeTestExpando[currentTestCase]) { var uri = _localhostUri(0, path, secure: secure, rawPath: rawPath); @@ -63,9 +63,8 @@ Future statusCodeForVirtDir(VirtualDirectory virtualDir, String path, followRedirects: followRedirects, ifModifiedSince: ifModifiedSince); _addRangeHeader(request, from, to); - return _withFakeRequest(virtualDir, request).then((response) { - return response.statusCode; - }); + var response = await _withFakeRequest(virtualDir, request); + return response.statusCode; } assert(_isFakeTestExpando[currentTestCase] == false); @@ -117,7 +116,7 @@ Future fetchStatusCode(int port, String path, } Future fetchHEaders(VirtualDirectory virDir, String path, - {int from, int to}) { + {int from, int to}) async { // if this is a fake test, then run the fake code path if (_isFakeTestExpando[currentTestCase]) { var uri = _localhostUri(0, path); @@ -125,39 +124,33 @@ Future fetchHEaders(VirtualDirectory virDir, String path, var request = FakeHttpRequest(uri); _addRangeHeader(request, from, to); - return _withFakeRequest(virDir, request).then((response) { - return response.headers; - }); + var response = await _withFakeRequest(virDir, request); + return response.headers; } assert(_isFakeTestExpando[currentTestCase] == false); - return _withServer(virDir, (port) { - return _headers(port, path, from, to); - }); + return _withServer(virDir, (port) => _headers(port, path, from, to)); } -Future fetchAsString(VirtualDirectory virtualDir, String path) { +Future fetchAsString(VirtualDirectory virtualDir, String path) async { // if this is a fake test, then run the fake code path if (_isFakeTestExpando[currentTestCase]) { var uri = _localhostUri(0, path); var request = FakeHttpRequest(uri); - return _withFakeRequest(virtualDir, request).then((response) { - return response.fakeContent; - }); + var response = await _withFakeRequest(virtualDir, request); + return response.fakeContent; } assert(_isFakeTestExpando[currentTestCase] == false); - return _withServer(virtualDir, (int port) { - return _fetchAsString(port, path); - }); + return _withServer(virtualDir, (int port) => _fetchAsString(port, path)); } Future> fetchAsBytes(VirtualDirectory virtualDir, String path, - {int from, int to}) { + {int from, int to}) async { // if this is a fake test, then run the fake code path if (_isFakeTestExpando[currentTestCase]) { var uri = _localhostUri(0, path); @@ -165,20 +158,18 @@ Future> fetchAsBytes(VirtualDirectory virtualDir, String path, var request = FakeHttpRequest(uri); _addRangeHeader(request, from, to); - return _withFakeRequest(virtualDir, request).then((response) { - return response.fakeContentBinary; - }); + var response = await _withFakeRequest(virtualDir, request); + return response.fakeContentBinary; } assert(_isFakeTestExpando[currentTestCase] == false); - return _withServer(virtualDir, (int port) { - return _fetchAsBytes(port, path, from, to); - }); + return _withServer( + virtualDir, (int port) => _fetchAsBytes(port, path, from, to)); } Future fetchContentAndResponse(VirtualDirectory virtualDir, String path, - {int from, int to}) { + {int from, int to}) async { // if this is a fake test, then run the fake code path if (_isFakeTestExpando[currentTestCase]) { var uri = _localhostUri(0, path); @@ -186,16 +177,14 @@ Future fetchContentAndResponse(VirtualDirectory virtualDir, String path, var request = FakeHttpRequest(uri); _addRangeHeader(request, from, to); - return _withFakeRequest(virtualDir, request).then((response) { - return [response.fakeContentBinary, response]; - }); + var response = await _withFakeRequest(virtualDir, request); + return [response.fakeContentBinary, response]; } assert(_isFakeTestExpando[currentTestCase] == false); - return _withServer(virtualDir, (int port) { - return _fetchContentAndResponse(port, path, from, to); - }); + return _withServer( + virtualDir, (int port) => _fetchContentAndResponse(port, path, from, to)); } Future _withFakeRequest( @@ -231,50 +220,54 @@ Future _withServer( } } -Future _headers(int port, String path, int from, int to) { +Future _headers(int port, String path, int from, int to) async { var client = HttpClient(); - return client - .get('localhost', port, path) - .then((request) { - _addRangeHeader(request, from, to); - return request.close(); - }) - .then((response) => response.drain().then((_) => response.headers)) - .whenComplete(() => client.close()); + try { + var request = await client.get('localhost', port, path); + _addRangeHeader(request, from, to); + var response = await request.close(); + await response.drain(); + return response.headers; + } finally { + client.close(); + } } -Future _fetchAsString(int port, String path) { +Future _fetchAsString(int port, String path) async { var client = HttpClient(); - return client - .get('localhost', port, path) - .then((request) => request.close()) - .then((response) => utf8.decodeStream(response.cast>())) - .whenComplete(() => client.close()); + try { + var request = await client.get('localhost', port, path); + var response = await request.close(); + return await utf8.decodeStream(response.cast>()); + } finally { + client.close(); + } } -Future> _fetchAsBytes(int port, String path, int from, int to) { +Future> _fetchAsBytes(int port, String path, int from, int to) async { var client = HttpClient(); - return client - .get('localhost', port, path) - .then((request) { - _addRangeHeader(request, from, to); - return request.close(); - }) - .then((response) => response.fold>([], (p, e) => p..addAll(e))) - .whenComplete(() => client.close()); + try { + var request = await client.get('localhost', port, path); + _addRangeHeader(request, from, to); + var response = await request.close(); + return await response.fold([], (p, e) => p..addAll(e)); + } finally { + client.close(); + } } -Future _fetchContentAndResponse(int port, String path, int from, int to) { +Future _fetchContentAndResponse( + int port, String path, int from, int to) async { var client = HttpClient(); - return client - .get('localhost', port, path) - .then((request) { - _addRangeHeader(request, from, to); - return request.close(); - }) - .then((response) => response - .fold([], (p, e) => p..addAll(e)).then((bytes) => [bytes, response])) - .whenComplete(() => client.close()); + try { + var request = await client.get('localhost', port, path); + _addRangeHeader(request, from, to); + var response = await request.close(); + var bytes = await response.fold([], (p, e) => p..addAll(e)); + return [bytes, response]; + } finally { + client.close(); + } } Uri _localhostUri(int port, String path, diff --git a/test/virtual_directory_test.dart b/test/virtual_directory_test.dart index 83739d5..9c6627e 100644 --- a/test/virtual_directory_test.dart +++ b/test/virtual_directory_test.dart @@ -24,146 +24,133 @@ void _testEncoding(name, expected, [bool create = true]) { void main() { group('serve-root', () { - testVirtualDir('dir-exists', (dir) { + testVirtualDir('dir-exists', (dir) async { var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/'); + expect(result, HttpStatus.notFound); }); - testVirtualDir('dir-not-exists', (dir) { + testVirtualDir('dir-not-exists', (dir) async { var virDir = VirtualDirectory(pathos.join('${dir.path}foo')); - return statusCodeForVirtDir(virDir, '/').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/'); + expect(result, HttpStatus.notFound); }); }); group('serve-file', () { group('top-level', () { - testVirtualDir('file-exists', (dir) { + testVirtualDir('file-exists', (dir) async { File('${dir.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/file'); + expect(result, HttpStatus.ok); }); - testVirtualDir('file-not-exists', (dir) { + testVirtualDir('file-not-exists', (dir) async { var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/file').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/file'); + expect(result, HttpStatus.notFound); }); }); group('in-dir', () { - testVirtualDir('file-exists', (dir) { + testVirtualDir('file-exists', (dir) async { var dir2 = Directory('${dir.path}/dir')..createSync(); File('${dir2.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/dir/file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/dir/file'); + expect(result, HttpStatus.ok); }); - testVirtualDir('file-not-exists', (dir) { + testVirtualDir('file-not-exists', (dir) async { Directory('${dir.path}/dir')..createSync(); File('${dir.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/dir/file').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/dir/file'); + expect(result, HttpStatus.notFound); }); }); }); group('serve-dir', () { group('top-level', () { - testVirtualDir('simple', (dir) { + testVirtualDir('simple', (dir) async { var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('Index of /')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('Index of /')); }); - testVirtualDir('files', (dir) { + testVirtualDir('files', (dir) async { var virDir = VirtualDirectory(dir.path); for (var i = 0; i < 10; i++) { File('${dir.path}/$i').createSync(); } virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('Index of /')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('Index of /')); }); - testVirtualDir('dir-href', (dir) { + testVirtualDir('dir-href', (dir) async { var virDir = VirtualDirectory(dir.path); Directory('${dir.path}/dir').createSync(); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('')); }); - testVirtualDir('dirs', (dir) { + testVirtualDir('dirs', (dir) async { var virDir = VirtualDirectory(dir.path); for (var i = 0; i < 10; i++) { Directory('${dir.path}/$i').createSync(); } virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('Index of /')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('Index of /')); }); - testVirtualDir('encoded-dir', (dir) { + testVirtualDir('encoded-dir', (dir) async { var virDir = VirtualDirectory(dir.path); Directory('${dir.path}/alert(\'hacked!\');').createSync(); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/alert(\'hacked!\');').then((result) { - expect(result, contains('/alert('hacked!');/')); - }); + var result = await fetchAsString(virDir, '/alert(\'hacked!\');'); + expect(result, contains('/alert('hacked!');/')); }); - testVirtualDir('non-ascii-dir', (dir) { + testVirtualDir('non-ascii-dir', (dir) async { var virDir = VirtualDirectory(dir.path); Directory('${dir.path}/æø').createSync(); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('æø')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('æø')); }); - testVirtualDir('content-type', (dir) { + testVirtualDir('content-type', (dir) async { var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return fetchHEaders(virDir, '/').then((headers) { - var contentType = headers.contentType.toString(); - expect(contentType, 'text/html; charset=utf-8'); - }); + var headers = await fetchHEaders(virDir, '/'); + var contentType = headers.contentType.toString(); + expect(contentType, 'text/html; charset=utf-8'); }); if (!Platform.isWindows) { - testVirtualDir('recursive-link', (dir) { + testVirtualDir('recursive-link', (dir) async { Link('${dir.path}/recursive')..createSync('.'); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return Future.wait([ + var result = await Future.wait([ fetchAsString(virDir, '/') .then((s) => s.contains('recursive/')), fetchAsString(virDir, '/').then((s) => !s.contains('../')), @@ -175,36 +162,33 @@ void main() { .then((s) => s.contains('../')), fetchAsString(virDir, '/recursive') .then((s) => s.contains('Index of /recursive')) - ]).then((result) { - expect(result, equals([true, true, true, true, true, true])); - }); + ]); + expect(result, equals([true, true, true, true, true, true])); }); - testVirtualDir('encoded-path', (dir) { + testVirtualDir('encoded-path', (dir) async { var virDir = VirtualDirectory(dir.path); Directory('${dir.path}/javascript:alert(document);"').createSync(); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('javascript%3Aalert(document)%3B%22/')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('javascript%3Aalert(document)%3B%22/')); }); - testVirtualDir('encoded-special', (dir) { + testVirtualDir('encoded-special', (dir) async { var virDir = VirtualDirectory(dir.path); Directory('${dir.path}/<>&"').createSync(); virDir.allowDirectoryListing = true; - return fetchAsString(virDir, '/').then((result) { - expect(result, contains('<>&"/')); - expect(result, contains('href="%3C%3E%26%22/"')); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, contains('<>&"/')); + expect(result, contains('href="%3C%3E%26%22/"')); }); } }); group('custom', () { - testVirtualDir('simple', (dir) { + testVirtualDir('simple', (dir) async { var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; virDir.directoryHandler = (dir2, request) { @@ -214,12 +198,11 @@ void main() { request.response.close(); }; - return fetchAsString(virDir, '/').then((result) { - expect(result, 'My handler /'); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, 'My handler /'); }); - testVirtualDir('index-1', (dir) { + testVirtualDir('index-1', (dir) async { File('${dir.path}/index.html').writeAsStringSync('index file'); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; @@ -229,12 +212,11 @@ void main() { return virDir.serveFile(File(indexUri.toFilePath()), request); }; - return fetchAsString(virDir, '/').then((result) { - expect(result, 'index file'); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, 'index file'); }); - testVirtualDir('index-2', (dir) { + testVirtualDir('index-2', (dir) async { Directory('${dir.path}/dir').createSync(); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; @@ -243,13 +225,12 @@ void main() { fail('not expected'); }; - return statusCodeForVirtDir(virDir, '/dir', followRedirects: false) - .then((result) { - expect(result, 301); - }); + var result = + await statusCodeForVirtDir(virDir, '/dir', followRedirects: false); + expect(result, 301); }); - testVirtualDir('index-3', (dir) { + testVirtualDir('index-3', (dir) async { File('${dir.path}/dir/index.html') ..createSync(recursive: true) ..writeAsStringSync('index file'); @@ -260,12 +241,11 @@ void main() { var indexUri = Uri.file(dir2.path).resolve('index.html'); return virDir.serveFile(File(indexUri.toFilePath()), request); }; - return fetchAsString(virDir, '/dir').then((result) { - expect(result, 'index file'); - }); + var result = await fetchAsString(virDir, '/dir'); + expect(result, 'index file'); }); - testVirtualDir('index-4', (dir) { + testVirtualDir('index-4', (dir) async { File('${dir.path}/dir/index.html') ..createSync(recursive: true) ..writeAsStringSync('index file'); @@ -276,14 +256,13 @@ void main() { var indexUri = Uri.file(dir2.path).resolve('index.html'); virDir.serveFile(File(indexUri.toFilePath()), request); }; - return fetchAsString(virDir, '/dir/').then((result) { - expect(result, 'index file'); - }); + var result = await fetchAsString(virDir, '/dir/'); + expect(result, 'index file'); }); }); group('path-prefix', () { - testVirtualDir('simple', (dir) { + testVirtualDir('simple', (dir) async { var virDir = VirtualDirectory(dir.path, pathPrefix: '/path'); virDir.allowDirectoryListing = true; virDir.directoryHandler = (d, request) { @@ -291,12 +270,11 @@ void main() { request.response.close(); }; - return statusCodeForVirtDir(virDir, '/path').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/path'); + expect(result, HttpStatus.ok); }); - testVirtualDir('trailing-slash', (dir) { + testVirtualDir('trailing-slash', (dir) async { var virDir = VirtualDirectory(dir.path, pathPrefix: '/path/'); virDir.allowDirectoryListing = true; virDir.directoryHandler = (d, request) { @@ -304,16 +282,14 @@ void main() { request.response.close(); }; - return statusCodeForVirtDir(virDir, '/path').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/path'); + expect(result, HttpStatus.ok); }); - testVirtualDir('not-matching', (dir) { + testVirtualDir('not-matching', (dir) async { var virDir = VirtualDirectory(dir.path, pathPrefix: '/path/'); - return statusCodeForVirtDir(virDir, '/').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/'); + expect(result, HttpStatus.notFound); }); }); }); @@ -321,84 +297,78 @@ void main() { group('links', () { if (!Platform.isWindows) { group('follow-links', () { - testVirtualDir('dir-link', (dir) { + testVirtualDir('dir-link', (dir) async { var dir2 = Directory('${dir.path}/dir2')..createSync(); Link('${dir.path}/dir3')..createSync('dir2'); File('${dir2.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); virDir.followLinks = true; - return statusCodeForVirtDir(virDir, '/dir3/file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/dir3/file'); + expect(result, HttpStatus.ok); }); - testVirtualDir('root-link', (dir) { + testVirtualDir('root-link', (dir) async { Link('${dir.path}/dir3')..createSync('.'); File('${dir.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); virDir.followLinks = true; - return statusCodeForVirtDir(virDir, '/dir3/file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/dir3/file'); + expect(result, HttpStatus.ok); }); group('bad-links', () { - testVirtualDir('absolute-link', (dir) { + testVirtualDir('absolute-link', (dir) async { File('${dir.path}/file')..createSync(); Link('${dir.path}/file2')..createSync('${dir.path}/file'); var virDir = VirtualDirectory(dir.path); virDir.followLinks = true; - return statusCodeForVirtDir(virDir, '/file2').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/file2'); + expect(result, HttpStatus.notFound); }); - testVirtualDir('relative-parent-link', (dir) { + testVirtualDir('relative-parent-link', (dir) async { var dir2 = Directory('${dir.path}/dir')..createSync(); File('${dir.path}/file')..createSync(); Link('${dir2.path}/file')..createSync('../file'); var virDir = VirtualDirectory(dir2.path); virDir.followLinks = true; - return statusCodeForVirtDir(virDir, '/dir3/file').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/dir3/file'); + expect(result, HttpStatus.notFound); }); }); }); group('not-follow-links', () { - testVirtualDir('dir-link', (dir) { + testVirtualDir('dir-link', (dir) async { var dir2 = Directory('${dir.path}/dir2')..createSync(); Link('${dir.path}/dir3')..createSync('dir2'); File('${dir2.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); virDir.followLinks = false; - return statusCodeForVirtDir(virDir, '/dir3/file').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/dir3/file'); + expect(result, HttpStatus.notFound); }); }); group('follow-links', () { group('no-root-jail', () { - testVirtualDir('absolute-link', (dir) { + testVirtualDir('absolute-link', (dir) async { File('${dir.path}/file')..createSync(); Link('${dir.path}/file2')..createSync('${dir.path}/file'); var virDir = VirtualDirectory(dir.path); virDir.followLinks = true; virDir.jailRoot = false; - return statusCodeForVirtDir(virDir, '/file2').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/file2'); + expect(result, HttpStatus.ok); }); - testVirtualDir('relative-parent-link', (dir) { + testVirtualDir('relative-parent-link', (dir) async { var dir2 = Directory('${dir.path}/dir')..createSync(); File('${dir.path}/file')..createSync(); Link('${dir2.path}/file')..createSync('../file'); @@ -406,9 +376,8 @@ void main() { virDir.followLinks = true; virDir.jailRoot = false; - return statusCodeForVirtDir(virDir, '/file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/file'); + expect(result, HttpStatus.ok); }); }); }); @@ -417,64 +386,58 @@ void main() { group('last-modified', () { group('file', () { - testVirtualDir('file-exists', (dir) { + testVirtualDir('file-exists', (dir) async { File('${dir.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); - return fetchHEaders(virDir, '/file').then((headers) { - expect(headers.value(HttpHeaders.lastModifiedHeader), isNotNull); - var lastModified = - HttpDate.parse(headers.value(HttpHeaders.lastModifiedHeader)); + var headers = await fetchHEaders(virDir, '/file'); + expect(headers.value(HttpHeaders.lastModifiedHeader), isNotNull); + var lastModified = + HttpDate.parse(headers.value(HttpHeaders.lastModifiedHeader)); - return statusCodeForVirtDir(virDir, '/file', - ifModifiedSince: lastModified); - }).then((result) { - expect(result, HttpStatus.notModified); - }); + var result = await statusCodeForVirtDir(virDir, '/file', + ifModifiedSince: lastModified); + expect(result, HttpStatus.notModified); }); - testVirtualDir('file-changes', (dir) { + testVirtualDir('file-changes', (dir) async { File('${dir.path}/file')..createSync(); var virDir = VirtualDirectory(dir.path); - return fetchHEaders(virDir, '/file').then((headers) { - expect(headers.value(HttpHeaders.lastModifiedHeader), isNotNull); - var lastModified = - HttpDate.parse(headers.value(HttpHeaders.lastModifiedHeader)); + var headers = await fetchHEaders(virDir, '/file'); + expect(headers.value(HttpHeaders.lastModifiedHeader), isNotNull); + var lastModified = + HttpDate.parse(headers.value(HttpHeaders.lastModifiedHeader)); - // Fake file changed by moving date back in time. - lastModified = lastModified.subtract(const Duration(seconds: 10)); + // Fake file changed by moving date back in time. + lastModified = lastModified.subtract(const Duration(seconds: 10)); - return statusCodeForVirtDir(virDir, '/file', - ifModifiedSince: lastModified); - }).then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/file', + ifModifiedSince: lastModified); + expect(result, HttpStatus.ok); }); }); }); group('content-type', () { group('mime-type', () { - testVirtualDir('from-path', (dir) { + testVirtualDir('from-path', (dir) async { File('${dir.path}/file.jpg')..createSync(); var virDir = VirtualDirectory(dir.path); - return fetchHEaders(virDir, '/file.jpg').then((headers) { - var contentType = headers.contentType.toString(); - expect(contentType, 'image/jpeg'); - }); + var headers = await fetchHEaders(virDir, '/file.jpg'); + var contentType = headers.contentType.toString(); + expect(contentType, 'image/jpeg'); }); - testVirtualDir('from-magic-number', (dir) { + testVirtualDir('from-magic-number', (dir) async { var file = File('${dir.path}/file.jpg')..createSync(); file.writeAsBytesSync([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); var virDir = VirtualDirectory(dir.path); - return fetchHEaders(virDir, '/file.jpg').then((headers) { - var contentType = headers.contentType.toString(); - expect(contentType, 'image/png'); - }); + var headers = await fetchHEaders(virDir, '/file.jpg'); + var contentType = headers.contentType.toString(); + expect(contentType, 'image/png'); }); }); }); @@ -488,154 +451,140 @@ void main() { virDir = VirtualDirectory(dir.path); } - testVirtualDir('range', (dir) { + testVirtualDir('range', (dir) async { prepare(dir); - Future test(int from, int to, [List expected, String contentRange]) { + Future check(int from, int to, + [List expected, String contentRange]) async { expected ??= fileContent.sublist(from, to + 1); contentRange ??= 'bytes $from-$to/${fileContent.length}'; - return fetchContentAndResponse(virDir, '/file', from: from, to: to) - .then(expectAsync1((result) { - var content = result[0]; - var response = result[1]; - expect(content, expected); - expect(response.headers[HttpHeaders.contentRangeHeader][0], - contentRange); - expect(expected.length, response.headers.contentLength); - expect(response.statusCode, HttpStatus.partialContent); - })); + var result = + await fetchContentAndResponse(virDir, '/file', from: from, to: to); + var content = result[0]; + var response = result[1]; + expect(content, expected); + expect( + response.headers[HttpHeaders.contentRangeHeader][0], contentRange); + expect(expected.length, response.headers.contentLength); + expect(response.statusCode, HttpStatus.partialContent); } - return Future.forEach([ - () => test(0, 0), - () => test(0, 1), - () => test(1, 2), - () => test(1, 9), - () => test(0, 9), - () => test(8, 9), - () => test(9, 9), - () => test(0, 10, fileContent, 'bytes 0-9/10'), - () => test(9, 10, [9], 'bytes 9-9/10'), - () => test(0, 1000, fileContent, 'bytes 0-9/10'), - ], (f) => f().then(expectAsync1((_) {}))); + await check(0, 0); + await check(0, 1); + await check(1, 2); + await check(1, 9); + await check(0, 9); + await check(8, 9); + await check(9, 9); + await check(0, 10, fileContent, 'bytes 0-9/10'); + await check(9, 10, [9], 'bytes 9-9/10'); + await check(0, 1000, fileContent, 'bytes 0-9/10'); }); - testVirtualDir('prefix-range', (dir) { + testVirtualDir('prefix-range', (dir) async { prepare(dir); - Future test(int from, + Future check(int from, [List expected, String contentRange, bool expectContentRange = true, - int expectedStatusCode = HttpStatus.partialContent]) { + int expectedStatusCode = HttpStatus.partialContent]) async { expected ??= fileContent.sublist(from, fileContent.length); if (contentRange == null && expectContentRange) { contentRange = 'bytes $from-' '${fileContent.length - 1}/' '${fileContent.length}'; } - return fetchContentAndResponse(virDir, '/file', from: from) - .then(expectAsync1((result) { - var content = result[0]; - var response = result[1]; - expect(content, expected); - if (expectContentRange) { - expect(response.headers[HttpHeaders.contentRangeHeader][0], - contentRange); - } else { - expect(response.headers[HttpHeaders.contentRangeHeader], null); - } - expect(response.statusCode, expectedStatusCode); - })); + var result = await fetchContentAndResponse(virDir, '/file', from: from); + var content = result[0]; + var response = result[1]; + expect(content, expected); + if (expectContentRange) { + expect(response.headers[HttpHeaders.contentRangeHeader][0], + contentRange); + } else { + expect(response.headers[HttpHeaders.contentRangeHeader], null); + } + expect(response.statusCode, expectedStatusCode); } - return Future.forEach([ - () => test(0), - () => test(1), - () => test(9), - () => test(10, fileContent, null, false, HttpStatus.ok), - () => test(11, fileContent, null, false, HttpStatus.ok), - () => test(1000, fileContent, null, false, HttpStatus.ok), - ], (f) => f().then(expectAsync1((_) {}))); + await check(0); + await check(1); + await check(9); + await check(10, fileContent, null, false, HttpStatus.ok); + await check(11, fileContent, null, false, HttpStatus.ok); + await check(1000, fileContent, null, false, HttpStatus.ok); }); - testVirtualDir('suffix-range', (dir) { + testVirtualDir('suffix-range', (dir) async { prepare(dir); - Future test(int to, [List expected, String contentRange]) { + Future check(int to, + [List expected, String contentRange]) async { expected ??= fileContent.sublist(fileContent.length - to, fileContent.length); contentRange ??= 'bytes ${fileContent.length - to}-' '${fileContent.length - 1}/' '${fileContent.length}'; - return fetchContentAndResponse(virDir, '/file', to: to) - .then(expectAsync1((result) { - var content = result[0]; - var response = result[1]; - expect(content, expected); - expect(response.headers[HttpHeaders.contentRangeHeader][0], - contentRange); - expect(response.statusCode, HttpStatus.partialContent); - })); + var result = await fetchContentAndResponse(virDir, '/file', to: to); + var content = result[0]; + var response = result[1]; + expect(content, expected); + expect( + response.headers[HttpHeaders.contentRangeHeader][0], contentRange); + expect(response.statusCode, HttpStatus.partialContent); } - return Future.forEach([ - () => test(1), - () => test(2), - () => test(9), - () => test(10), - () => test(11, fileContent, 'bytes 0-9/10'), - () => test(1000, fileContent, 'bytes 0-9/10') - ], (f) => f().then(expectAsync1((_) {}))); + await check(1); + await check(2); + await check(9); + await check(10); + await check(11, fileContent, 'bytes 0-9/10'); + await check(1000, fileContent, 'bytes 0-9/10'); }); - testVirtualDir('unsatisfiable-range', (dir) { + testVirtualDir('unsatisfiable-range', (dir) async { prepare(dir); - Future test(int from, int to) { - return fetchContentAndResponse(virDir, '/file', from: from, to: to) - .then(expectAsync1((result) { - var content = result[0]; - var response = result[1]; - expect(content.length, 0); - expect(response.headers[HttpHeaders.contentRangeHeader], isNull); - expect(response.statusCode, HttpStatus.requestedRangeNotSatisfiable); - })); + Future check(int from, int to) async { + var result = + await fetchContentAndResponse(virDir, '/file', from: from, to: to); + var content = result[0]; + var response = result[1]; + expect(content.length, 0); + expect(response.headers[HttpHeaders.contentRangeHeader], isNull); + expect(response.statusCode, HttpStatus.requestedRangeNotSatisfiable); } - return Future.forEach( - [() => test(10, 11), () => test(10, 1000), () => test(1000, 1000)], - (f) => f().then(expectAsync1((_) {}))); + await check(10, 11); + await check(10, 1000); + await check(1000, 1000); }); - testVirtualDir('invalid-range', (dir) { + testVirtualDir('invalid-range', (dir) async { prepare(dir); - Future test(int from, int to) { - return fetchContentAndResponse(virDir, '/file', from: from, to: to) - .then(expectAsync1((result) { - var content = result[0]; - var response = result[1]; - expect(content, fileContent); - expect(response.headers[HttpHeaders.contentRangeHeader], isNull); - expect(response.statusCode, HttpStatus.ok); - })); + Future check(int from, int to) async { + var result = + await fetchContentAndResponse(virDir, '/file', from: from, to: to); + var content = result[0]; + var response = result[1]; + expect(content, fileContent); + expect(response.headers[HttpHeaders.contentRangeHeader], isNull); + expect(response.statusCode, HttpStatus.ok); } - return Future.forEach([ - () => test(1, 0), - () => test(10, 0), - () => test(1000, 999), - () => test(null, 0), // This is effectively range 10-9. - ], (f) => f().then(expectAsync1((_) {}))); + await check(1, 0); + await check(10, 0); + await check(1000, 999); + await check(null, 0); // This is effectively range 10-9. }); }); group('error-page', () { - testVirtualDir('default', (dir) { + testVirtualDir('default', (dir) async { var virDir = VirtualDirectory(pathos.join(dir.path, 'foo')); - return fetchAsString(virDir, '/').then((result) { - expect(result, matches(RegExp('404.*Not Found'))); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, matches(RegExp('404.*Not Found'))); }); - testVirtualDir('custom', (dir) { + testVirtualDir('custom', (dir) async { var virDir = VirtualDirectory(pathos.join(dir.path, 'foo')); virDir.errorPageHandler = (request) { @@ -644,74 +593,67 @@ void main() { request.response.close(); }; - return fetchAsString(virDir, '/').then((result) { - expect(result, 'my-page 404'); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, 'my-page 404'); }); }); group('escape-root', () { - testVirtualDir('escape1', (dir) { + testVirtualDir('escape1', (dir) async { var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return statusCodeForVirtDir(virDir, '/../').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/../'); + expect(result, HttpStatus.notFound); }); - testVirtualDir('escape2', (dir) { + testVirtualDir('escape2', (dir) async { Directory('${dir.path}/dir').createSync(); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return statusCodeForVirtDir(virDir, '/dir/../../').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/dir/../../'); + expect(result, HttpStatus.notFound); }); }, skip: 'Broken. Likely due to dart:core Uri changes.' 'See https://github.com/dart-lang/http_server/issues/40'); group('url-decode', () { - testVirtualDir('with-space', (dir) { + testVirtualDir('with-space', (dir) async { File('${dir.path}/my file')..createSync(); var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/my file').then((result) { - expect(result, HttpStatus.ok); - }); + var result = await statusCodeForVirtDir(virDir, '/my file'); + expect(result, HttpStatus.ok); }); - testVirtualDir('encoded-space', (dir) { + testVirtualDir('encoded-space', (dir) async { File('${dir.path}/my file')..createSync(); var virDir = VirtualDirectory(dir.path); - return statusCodeForVirtDir(virDir, '/my%20file').then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/my%20file'); + expect(result, HttpStatus.notFound); }); - testVirtualDir('encoded-path-separator', (dir) { + testVirtualDir('encoded-path-separator', (dir) async { Directory('${dir.path}/a').createSync(); Directory('${dir.path}/a/b').createSync(); Directory('${dir.path}/a/b/c').createSync(); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return statusCodeForVirtDir(virDir, '/a%2fb/c', rawPath: true) - .then((result) { - expect(result, HttpStatus.notFound); - }); + var result = + await statusCodeForVirtDir(virDir, '/a%2fb/c', rawPath: true); + expect(result, HttpStatus.notFound); }); - testVirtualDir('encoded-null', (dir) { + testVirtualDir('encoded-null', (dir) async { var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; - return statusCodeForVirtDir(virDir, '/%00', rawPath: true).then((result) { - expect(result, HttpStatus.notFound); - }); + var result = await statusCodeForVirtDir(virDir, '/%00', rawPath: true); + expect(result, HttpStatus.notFound); }); group('broken', () { @@ -728,7 +670,7 @@ void main() { }); group('serve-file', () { - testVirtualDir('from-dir-handler', (dir) { + testVirtualDir('from-dir-handler', (dir) async { File('${dir.path}/file')..writeAsStringSync('file contents'); var virDir = VirtualDirectory(dir.path); virDir.allowDirectoryListing = true; @@ -737,12 +679,10 @@ void main() { return virDir.serveFile(File('${d.path}/file'), request); }; - return fetchAsString(virDir, '/').then((result) { - expect(result, 'file contents'); - return fetchHEaders(virDir, '/').then(expectAsync1((headers) { - expect('file contents'.length, headers.contentLength); - })); - }); + var result = await fetchAsString(virDir, '/'); + expect(result, 'file contents'); + var headers = await fetchHEaders(virDir, '/'); + expect('file contents'.length, headers.contentLength); }); }); } diff --git a/test/virtual_host_test.dart b/test/virtual_host_test.dart index 9a30998..7f85bbc 100644 --- a/test/virtual_host_test.dart +++ b/test/virtual_host_test.dart @@ -13,202 +13,132 @@ import 'utils.dart'; void main() { setUpAll(setupSecure); - test('empty-host', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - VirtualHost(server); - return fetchStatusCode(server.port, '/').whenComplete(server.close); - }), - completion(equals(HttpStatus.forbidden))); - }); - - test('empty-host-unhandled', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect(virHost.unhandled.first.then((request) { - request.response.close(); - }), completion(isNull)); - return fetchStatusCode(server.port, '/').whenComplete(server.close); - }), - completion(equals(HttpStatus.ok))); - }); + group('virtual host', () { + HttpServer server; + VirtualHost virHost; - test('single-host', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('*.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return fetchStatusCode(server.port, '/', host: 'my.host.com') - .whenComplete(server.close); - }), - completion(equals(HttpStatus.ok))); - }); - - test('multiple-host', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('*.host1.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host2.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host3.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return Future.wait([ - fetchStatusCode(server.port, '/', host: 'my.host1.com'), - fetchStatusCode(server.port, '/', host: 'my.host2.com'), - fetchStatusCode(server.port, '/', host: 'my.host3.com') - ]).whenComplete(server.close); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok]))); - }); + setUp(() async { + server = await HttpServer.bind('localhost', 0); + virHost = VirtualHost(server); + }); - test('multiple-source-https', () { - expect( - Future.wait([ - HttpServer.bind('localhost', 0), - HttpServer.bindSecure('localhost', 0, serverContext) - ]).then((servers) { - var virHost = VirtualHost(); - virHost.addSource(servers[0]); - virHost.addSource(servers[1]); - virHost.unhandled.listen((request) { - request.response.close(); - }); - return Future.wait([ - fetchStatusCode(servers[0].port, '/', host: 'myhost1.com'), - fetchStatusCode(servers[1].port, '/', - host: 'myhost2.com', secure: true) - ]).whenComplete(() => servers.forEach((s) => s.close())); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok]))); - }); + tearDown(() async { + await server.close(); + }); + test('empty-host', () async { + var statusCode = await fetchStatusCode(server.port, '/'); + expect(statusCode, equals(HttpStatus.forbidden)); + }); - group('domain', () { - test('specific-sub-domain', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('my1.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('my2.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('my3.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return Future.wait([ - fetchStatusCode(server.port, '/', host: 'my1.host.com'), - fetchStatusCode(server.port, '/', host: 'my2.host.com'), - fetchStatusCode(server.port, '/', host: 'my3.host.com') - ]).whenComplete(server.close); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok]))); + test('empty-host-unhandled', () async { + var statusCodes = fetchStatusCode(server.port, '/'); + var request = await virHost.unhandled.first; + await request.response.close(); + expect(await statusCodes, equals(HttpStatus.ok)); }); - test('wildcard-sub-domain', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('*.host1.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host2.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host3.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return Future.wait([ - fetchStatusCode(server.port, '/', host: 'my.host1.com'), - fetchStatusCode(server.port, '/', host: 'my.host2.com'), - fetchStatusCode(server.port, '/', host: 'my.host3.com') - ]).whenComplete(server.close); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok]))); + test('single-host', () async { + var host = virHost.addHost('*.host.com'); + var statusCode = fetchStatusCode(server.port, '/', host: 'my.host.com'); + var request = await host.first; + await request.response.close(); + expect(await statusCode, equals(HttpStatus.ok)); }); - test('mix-sub-domain', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('my1.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('my2.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return Future.wait([ - fetchStatusCode(server.port, '/', host: 'my1.host.com'), - fetchStatusCode(server.port, '/', host: 'my2.host.com'), - fetchStatusCode(server.port, '/', host: 'my3.host.com') - ]).whenComplete(server.close); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok]))); + test('multiple-host', () async {}); + + group('domain', () { + test('specific-sub-domain', () async { + var hosts = [ + virHost.addHost('my1.host.com'), + virHost.addHost('my2.host.com'), + virHost.addHost('my3.host.com'), + ]; + var statusCodes = [ + fetchStatusCode(server.port, '/', host: 'my1.host.com'), + fetchStatusCode(server.port, '/', host: 'my2.host.com'), + fetchStatusCode(server.port, '/', host: 'my3.host.com'), + ]; + for (var host in hosts) { + var request = await host.first; + await request.response.close(); + } + expect(await Future.wait(statusCodes), + equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok])); + }); + + test('wildcard-sub-domain', () async { + var hosts = [ + virHost.addHost('*.host1.com'), + virHost.addHost('*.host2.com'), + virHost.addHost('*.host3.com'), + ]; + var statusCodes = [ + fetchStatusCode(server.port, '/', host: 'my.host1.com'), + fetchStatusCode(server.port, '/', host: 'my.host2.com'), + fetchStatusCode(server.port, '/', host: 'my.host3.com'), + ]; + for (var host in hosts) { + var request = await host.first; + await request.response.close(); + } + expect(await Future.wait(statusCodes), + equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok])); + }); + + test('mix-sub-domain', () async { + var hosts = [ + virHost.addHost('my1.host.com'), + virHost.addHost('my2.host.com'), + virHost.addHost('*.host.com'), + ]; + var statusCodes = [ + fetchStatusCode(server.port, '/', host: 'my1.host.com'), + fetchStatusCode(server.port, '/', host: 'my2.host.com'), + fetchStatusCode(server.port, '/', host: 'my3.host.com'), + ]; + for (var host in hosts) { + var request = await host.first; + await request.response.close(); + } + expect(await Future.wait(statusCodes), + equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok])); + }); + + test('wildcard', () async { + var hosts = [ + virHost.addHost('*'), + virHost.addHost('*.com'), + virHost.addHost('*.host.com'), + ]; + var statusCodes = [ + fetchStatusCode(server.port, '/', host: 'some.host.dk'), + fetchStatusCode(server.port, '/', host: 'my.host2.com'), + fetchStatusCode(server.port, '/', host: 'long.sub.of.host.com'), + ]; + for (var host in hosts) { + var request = await host.first; + await request.response.close(); + } + expect(await Future.wait(statusCodes), + equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok])); + }); }); - test('wildcard', () { - expect( - HttpServer.bind('localhost', 0).then((server) { - var virHost = VirtualHost(server); - expect( - virHost.addHost('*').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - expect( - virHost.addHost('*.host.com').first.then((request) { - request.response.close(); - }), - completion(isNull)); - return Future.wait([ - fetchStatusCode(server.port, '/', host: 'some.host.dk'), - fetchStatusCode(server.port, '/', host: 'my.host2.com'), - fetchStatusCode(server.port, '/', host: 'long.sub.of.host.com') - ]).whenComplete(server.close); - }), - completion(equals([HttpStatus.ok, HttpStatus.ok, HttpStatus.ok]))); + test('multiple-source-https', () async { + var secondServer = + await HttpServer.bindSecure('localhost', 0, serverContext); + virHost.addSource(secondServer); + virHost.unhandled.listen((request) { + request.response.close(); + }); + var statusCodes = await Future.wait([ + fetchStatusCode(server.port, '/', host: 'myhost1.com'), + fetchStatusCode(secondServer.port, '/', + host: 'myhost2.com', secure: true) + ]); + expect(statusCodes, [HttpStatus.ok, HttpStatus.ok]); + await secondServer.close(); }); test('duplicate-domain', () {