diff --git a/CHANGELOG.md b/CHANGELOG.md index 5598e4df..503ecb49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.1.3 +* Apply lints. +* Pin to Dart `>=2.0.0 <3.0.0`. +* Use at least version `2.0.0-rc.0` of `angel_framework`. + # 2.1.2+1 * Fix a typo that prevented `Range` requests from working. diff --git a/README.md b/README.md index 288e05d9..f20e9a1e 100644 --- a/README.md +++ b/README.md @@ -25,20 +25,20 @@ import 'package:angel_static/angel_static.dart'; import 'package:file/local.dart'; main() async { - var app = new Angel(); + var app = Angel(); var fs = const LocalFileSystem(); // Normal static server - var vDir = new VirtualDirectory(app, fs, source: new Directory('./public')); + var vDir = VirtualDirectory(app, fs, source: Directory('./public')); // Send Cache-Control, ETag, etc. as well - var vDir = new CachingVirtualDirectory(app, fs, source: new Directory('./public')); + var vDir = CachingVirtualDirectory(app, fs, source: Directory('./public')); // Mount the VirtualDirectory's request handler app.fallback(vDir.handleRequest); // Start your server!!! - await new AngelHttp(app).startServer(); + await AngelHttp(app).startServer(); } ``` @@ -49,7 +49,7 @@ the user is requesting that file. This can be very useful for SPA's. ```dart // Create VirtualDirectory as well -var vDir = new CachingVirtualDirectory(...); +var vDir = CachingVirtualDirectory(...); // Mount it app.fallback(vDir.handleRequest); diff --git a/analysis_options.yaml b/analysis_options.yaml index eae1e42a..085be64d 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,3 +1,8 @@ +include: package:pedantic/analysis_options.yaml analyzer: strong-mode: - implicit-casts: false \ No newline at end of file + implicit-casts: false +linter: + rules: + - unnecessary_const + - unnecessary_new \ No newline at end of file diff --git a/example/main.dart b/example/main.dart index b923181c..61791fda 100644 --- a/example/main.dart +++ b/example/main.dart @@ -5,10 +5,10 @@ import 'package:file/local.dart'; import 'package:logging/logging.dart'; main(List args) async { - var app = new Angel(); - var http = new AngelHttp(app); + var app = Angel(); + var http = AngelHttp(app); var fs = const LocalFileSystem(); - var vDir = new CachingVirtualDirectory( + var vDir = CachingVirtualDirectory( app, fs, allowDirectoryListing: true, @@ -24,7 +24,7 @@ main(List args) async { ..addExtension('md', 'text/plain') ..addExtension('yaml', 'text/plain'); - app.logger = new Logger('example') + app.logger = Logger('example') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); @@ -32,6 +32,7 @@ main(List args) async { }); app.fallback(vDir.handleRequest); + app.fallback((req, res) => throw AngelHttpException.notFound()); var server = await http.startServer('127.0.0.1', 3000); print('Serving from ${vDir.source.path}'); diff --git a/lib/src/cache.dart b/lib/src/cache.dart index b3edbb37..cad01d39 100644 --- a/lib/src/cache.dart +++ b/lib/src/cache.dart @@ -12,7 +12,7 @@ String accessLevelToString(CacheAccessLevel accessLevel) { case CacheAccessLevel.PUBLIC: return 'public'; default: - throw new ArgumentError('Unrecognized cache access level: $accessLevel'); + throw ArgumentError('Unrecognized cache access level: $accessLevel'); } } @@ -38,16 +38,16 @@ class CachingVirtualDirectory extends VirtualDirectory { final int maxAge; CachingVirtualDirectory(Angel app, FileSystem fileSystem, - {this.accessLevel: CacheAccessLevel.PUBLIC, + {this.accessLevel = CacheAccessLevel.PUBLIC, Directory source, bool debug, Iterable indexFileNames, - this.maxAge: 0, - this.noCache: false, - this.onlyInProduction: false, - this.useEtags: true, + this.maxAge = 0, + this.noCache = false, + this.onlyInProduction = false, + this.useEtags = true, bool allowDirectoryListing, - bool useBuffer: false, + bool useBuffer = false, String publicPath, callback(File file, RequestContext req, ResponseContext res)}) : super(app, fileSystem, @@ -63,7 +63,7 @@ class CachingVirtualDirectory extends VirtualDirectory { File file, FileStat stat, RequestContext req, ResponseContext res) { res.headers['accept-ranges'] = 'bytes'; - if (onlyInProduction == true && req.app.isProduction != true) { + if (onlyInProduction == true && req.app.environment.isProduction != true) { return super.serveFile(file, stat, req, res); } @@ -105,12 +105,12 @@ class CachingVirtualDirectory extends VirtualDirectory { return super.serveFile(file, stat, req, res); } - return new Future.value(false); + return Future.value(false); } else if (ifRange) { return super.serveFile(file, stat, req, res); } } catch (_) { - throw new AngelHttpException.badRequest( + throw AngelHttpException.badRequest( message: 'Invalid date for ${ifRange ? 'if-range' : 'if-not-modified-since'} header.'); } @@ -143,7 +143,7 @@ class CachingVirtualDirectory extends VirtualDirectory { if (!hasBeenModified) { res.statusCode = 304; setCachedHeaders(stat.modified, req, res); - return new Future.value(false); + return Future.value(false); } } else { return super.serveFile(file, stat, req, res); @@ -172,7 +172,7 @@ class CachingVirtualDirectory extends VirtualDirectory { ..['last-modified'] = HttpDate.format(modified); if (maxAge != null) { - var expiry = new DateTime.now().add(new Duration(seconds: maxAge ?? 0)); + var expiry = DateTime.now().add(Duration(seconds: maxAge ?? 0)); res.headers['expires'] = HttpDate.format(expiry); } } diff --git a/lib/src/virtual_directory.dart b/lib/src/virtual_directory.dart index 1b85d584..4eb0cd9e 100644 --- a/lib/src/virtual_directory.dart +++ b/lib/src/virtual_directory.dart @@ -5,8 +5,8 @@ import 'package:http_parser/http_parser.dart'; import 'package:path/path.dart' as p; import 'package:range_header/range_header.dart'; -final RegExp _param = new RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?'); -final RegExp _straySlashes = new RegExp(r'(^/+)|(/+$)'); +final RegExp _param = RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?'); +final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); String _pathify(String path) { var p = path.replaceAll(_straySlashes, ''); @@ -54,16 +54,16 @@ class VirtualDirectory { VirtualDirectory(this.app, this.fileSystem, {Directory source, - this.indexFileNames: const ['index.html'], - this.publicPath: '/', + this.indexFileNames = const ['index.html'], + this.publicPath = '/', this.callback, - this.allowDirectoryListing: false, - this.useBuffer: false}) { + this.allowDirectoryListing = false, + this.useBuffer = false}) { _prefix = publicPath.replaceAll(_straySlashes, ''); if (source != null) { _source = source; } else { - String dirPath = app.isProduction ? './build/web' : './web'; + String dirPath = app.environment.isProduction ? './build/web' : './web'; _source = fileSystem.directory(dirPath); } } @@ -71,11 +71,11 @@ class VirtualDirectory { /// Responds to incoming HTTP requests. Future handleRequest(RequestContext req, ResponseContext res) { if (req.method != 'GET' && req.method != 'HEAD') - return new Future.value(true); + return Future.value(true); var path = req.uri.path.replaceAll(_straySlashes, ''); if (_prefix?.isNotEmpty == true && !path.startsWith(_prefix)) - return new Future.value(true); + return Future.value(true); return servePath(path, req, res); } @@ -91,11 +91,11 @@ class VirtualDirectory { return (RequestContext req, ResponseContext res) { var path = req.path.replaceAll(_straySlashes, ''); - if (path == vPath) return new Future.value(true); + if (path == vPath) return Future.value(true); if (accepts?.isNotEmpty == true) { if (!accepts.any((x) => req.accepts(x, strict: true))) - return new Future.value(true); + return Future.value(true); } return servePath(vPath, req, res); @@ -108,7 +108,7 @@ class VirtualDirectory { if (_prefix.isNotEmpty) { // Only replace the *first* incidence // Resolve: https://github.com/angel-dart/angel/issues/41 - path = path.replaceFirst(new RegExp('^' + _pathify(_prefix)), ''); + path = path.replaceFirst(RegExp('^' + _pathify(_prefix)), ''); } if (path.isEmpty) path = '.'; @@ -151,7 +151,7 @@ class VirtualDirectory { } if (allowDirectoryListing == true) { - res.contentType = new MediaType('text', 'html'); + res.contentType = MediaType('text', 'html'); res ..write('') ..write('') @@ -165,7 +165,7 @@ class VirtualDirectory { List entities = await directory .list(followLinks: false) .toList() - .then((l) => new List.from(l)); + .then((l) => List.from(l)); entities.sort((a, b) { if (a is Directory) { if (b is Directory) return a.path.compareTo(b.path); @@ -213,8 +213,8 @@ class VirtualDirectory { (mimeType?.isNotEmpty == true && value?.contains(mimeType) == true) || value?.contains('*/*') == true; if (!acceptable) - throw new AngelHttpException( - new UnsupportedError( + throw AngelHttpException( + UnsupportedError( 'Client requested $value, but server wanted to send $mimeType.'), statusCode: 406, message: '406 Not Acceptable'); @@ -237,16 +237,16 @@ class VirtualDirectory { res.headers['accept-ranges'] = 'bytes'; _ensureContentTypeAllowed(type, req); res.headers['accept-ranges'] = 'bytes'; - res.contentType = new MediaType.parse(type); + res.contentType = MediaType.parse(type); if (useBuffer == true) res.useBuffer(); if (req.headers.value('range')?.startsWith('bytes=') != true) { await res.streamFile(file); } else { - var header = new RangeHeader.parse(req.headers.value('range')); + var header = RangeHeader.parse(req.headers.value('range')); var items = RangeHeader.foldItems(header.items); var totalFileSize = await file.length(); - header = new RangeHeader(items); + header = RangeHeader(items); for (var item in header.items) { bool invalid = false; @@ -257,23 +257,23 @@ class VirtualDirectory { invalid = item.end == -1; if (invalid) { - throw new AngelHttpException( - new Exception("Semantically invalid, or unbounded range."), + throw AngelHttpException( + Exception("Semantically invalid, or unbounded range."), statusCode: 416, message: "Semantically invalid, or unbounded range."); } // Ensure it's within range. if (item.start >= totalFileSize || item.end >= totalFileSize) { - throw new AngelHttpException( - new Exception("Given range $item is out of bounds."), + throw AngelHttpException( + Exception("Given range $item is out of bounds."), statusCode: 416, message: "Given range $item is out of bounds."); } } if (header.items.isEmpty) { - throw new AngelHttpException(null, + throw AngelHttpException(null, statusCode: 416, message: '`Range` header may not be empty.'); } else if (header.items.length == 1) { var item = header.items[0]; @@ -298,7 +298,7 @@ class VirtualDirectory { } } - res.contentType = new MediaType.parse( + res.contentType = MediaType.parse( app.mimeTypeResolver.lookup(file.path) ?? 'application/octet-stream'); res.statusCode = 206; @@ -307,7 +307,7 @@ class VirtualDirectory { await stream.pipe(res); return false; } else { - var transformer = new RangeHeaderTransformer( + var transformer = RangeHeaderTransformer( header, app.mimeTypeResolver.lookup(file.path) ?? 'application/octet-stream', @@ -315,7 +315,7 @@ class VirtualDirectory { res.statusCode = 206; res.headers['content-length'] = transformer.computeContentLength(totalFileSize).toString(); - res.contentType = new MediaType( + res.contentType = MediaType( 'multipart', 'byteranges', {'boundary': transformer.boundary}); await file.openRead().transform(transformer).pipe(res); return false; diff --git a/pubspec.yaml b/pubspec.yaml index 8948b2a5..5bfde275 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,12 @@ name: angel_static description: Static server middleware for Angel. Also capable of serving Range responses. environment: - sdk: ">=1.8.0 <3.0.0" + sdk: ">=2.0.0 <3.0.0" homepage: https://github.com/angel-dart/static author: Tobe O version: 2.1.2+1 dependencies: - angel_framework: ^2.0.0-alpha + angel_framework: ^2.0.0-rc.0 convert: ^2.0.0 crypto: ^2.0.0 file: ^5.0.0 @@ -18,4 +18,5 @@ dev_dependencies: http: logging: ^0.11.0 matcher: ^0.12.0 + pedantic: ^1.0.0 test: ^1.0.0 diff --git a/test/all_test.dart b/test/all_test.dart index b7526785..0e337b9c 100644 --- a/test/all_test.dart +++ b/test/all_test.dart @@ -12,22 +12,22 @@ main() { AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); String url; - Client client = new Client(); + Client client = Client(); setUp(() async { - app = new Angel(); - http = new AngelHttp(app); - app.logger = new Logger('angel')..onRecord.listen(print); + app = Angel(); + http = AngelHttp(app); + app.logger = Logger('angel')..onRecord.listen(print); app.fallback( - new VirtualDirectory(app, const LocalFileSystem(), + VirtualDirectory(app, const LocalFileSystem(), source: testDir, publicPath: '/virtual', indexFileNames: ['index.txt']).handleRequest, ); app.fallback( - new VirtualDirectory(app, const LocalFileSystem(), + VirtualDirectory(app, const LocalFileSystem(), source: testDir, useBuffer: true, indexFileNames: ['index.php', 'index.txt']).handleRequest, diff --git a/test/cache_sample.dart b/test/cache_sample.dart index aaab4012..8f9c28bd 100644 --- a/test/cache_sample.dart +++ b/test/cache_sample.dart @@ -8,11 +8,11 @@ main() async { Angel app; AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); - app = new Angel(); - http = new AngelHttp(app); + app = Angel(); + http = AngelHttp(app); app.fallback( - new CachingVirtualDirectory(app, const LocalFileSystem(), + CachingVirtualDirectory(app, const LocalFileSystem(), source: testDir, maxAge: 350, onlyInProduction: false, diff --git a/test/cache_test.dart b/test/cache_test.dart index 83ebce65..c0aba9cb 100644 --- a/test/cache_test.dart +++ b/test/cache_test.dart @@ -14,14 +14,14 @@ main() { AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); String url; - Client client = new Client(); + Client client = Client(); setUp(() async { - app = new Angel(); - http = new AngelHttp(app); + app = Angel(); + http = AngelHttp(app); app.fallback( - new CachingVirtualDirectory(app, const LocalFileSystem(), + CachingVirtualDirectory(app, const LocalFileSystem(), source: testDir, maxAge: 350, onlyInProduction: false, //publicPath: '/virtual', indexFileNames: ['index.txt']).handleRequest, @@ -31,7 +31,7 @@ main() { app.dumpTree(showMatchers: true); - app.logger = new Logger('angel_static') + app.logger = Logger('angel_static') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); @@ -63,7 +63,7 @@ main() { test('if-modified-since', () async { var response = await client.get("$url", headers: { 'if-modified-since': - HttpDate.format(new DateTime.now().add(new Duration(days: 365))) + HttpDate.format(DateTime.now().add(Duration(days: 365))) }); print('Response status: ${response.statusCode}'); diff --git a/test/issue41_test.dart b/test/issue41_test.dart index e4bd0938..b02cb245 100644 --- a/test/issue41_test.dart +++ b/test/issue41_test.dart @@ -23,11 +23,11 @@ main() async { .readAsString(); // Initialize app - var app = new Angel(); - app.logger = new Logger('angel')..onRecord.listen(print); + var app = Angel(); + app.logger = Logger('angel')..onRecord.listen(print); app.fallback( - new VirtualDirectory(app, const LocalFileSystem(), + VirtualDirectory(app, const LocalFileSystem(), source: swaggerUiDistDir, publicPath: 'swagger/') .handleRequest, ); diff --git a/test/push_state_test.dart b/test/push_state_test.dart index 8aede873..1312407f 100644 --- a/test/push_state_test.dart +++ b/test/push_state_test.dart @@ -11,7 +11,7 @@ main() { TestClient client; setUp(() async { - fileSystem = new MemoryFileSystem(); + fileSystem = MemoryFileSystem(); var webDir = fileSystem.directory('web'); await webDir.create(recursive: true); @@ -19,9 +19,9 @@ main() { var indexFile = webDir.childFile('index.html'); await indexFile.writeAsString('index'); - app = new Angel(); + app = Angel(); - var vDir = new VirtualDirectory( + var vDir = VirtualDirectory( app, fileSystem, source: webDir, @@ -32,7 +32,7 @@ main() { ..fallback(vDir.pushState('index.html')) ..fallback((req, res) => 'Fallback'); - app.logger = new Logger('push_state') + app.logger = Logger('push_state') ..onRecord.listen( (rec) { print(rec);