diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ddb1906..c1c5e671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,10 @@ * Added html_builder and migrated to 2.0.0 (1/1 tests passed) * Migrated hot to 4.0.0 (0/0 tests passed) * Added range_header and migrated to 3.0.0 (12/12 tests passed) -* Updated static to 3.0.0 (in progress) -* Update basic-sdk-2.12.x boilerplate (in progress) +* Updated static to 4.0.0 (in progress) +* Update basic-sdk-2.12.x_nnbd boilerplate (in progress) +* Updated angel_serialize to 5.0.0 (in progress) +* Updated angel_serialize_generator to 5.0.0 (in progress) # 3.0.0 (Non NNBD) * Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0" diff --git a/packages/static/example/main.dart b/packages/static/example/main.dart index 16e4ad08..477bd093 100644 --- a/packages/static/example/main.dart +++ b/packages/static/example/main.dart @@ -35,6 +35,6 @@ void main(List args) async { app.fallback((req, res) => throw AngelHttpException.notFound()); var server = await http.startServer('127.0.0.1', 3000); - print('Serving from ${vDir.source.path}'); + print('Serving from ${vDir.source!.path}'); print('Listening at http://${server.address.address}:${server.port}'); } diff --git a/packages/static/lib/src/cache.dart b/packages/static/lib/src/cache.dart index 13042cdd..513c1e1e 100644 --- a/packages/static/lib/src/cache.dart +++ b/packages/static/lib/src/cache.dart @@ -39,17 +39,17 @@ class CachingVirtualDirectory extends VirtualDirectory { CachingVirtualDirectory(Angel app, FileSystem fileSystem, {this.accessLevel = CacheAccessLevel.PUBLIC, - Directory source, - bool debug, - Iterable indexFileNames, + Directory? source, + bool? debug, + Iterable? indexFileNames, this.maxAge = 0, this.noCache = false, this.onlyInProduction = false, this.useEtags = true, - bool allowDirectoryListing, + bool? allowDirectoryListing, bool useBuffer = false, - String publicPath, - Function(File file, RequestContext req, ResponseContext res) callback}) + String? publicPath, + Function(File file, RequestContext req, ResponseContext res)? callback}) : super(app, fileSystem, source: source, indexFileNames: indexFileNames ?? ['index.html'], @@ -63,26 +63,26 @@ class CachingVirtualDirectory extends VirtualDirectory { File file, FileStat stat, RequestContext req, ResponseContext res) { res.headers['accept-ranges'] = 'bytes'; - if (onlyInProduction == true && req.app.environment.isProduction != true) { + if (onlyInProduction == true && req.app!.environment.isProduction != true) { return super.serveFile(file, stat, req, res); } var shouldNotCache = noCache == true; if (!shouldNotCache) { - shouldNotCache = req.headers.value('cache-control') == 'no-cache' || - req.headers.value('pragma') == 'no-cache'; + shouldNotCache = req.headers!.value('cache-control') == 'no-cache' || + req.headers!.value('pragma') == 'no-cache'; } if (shouldNotCache) { res.headers['cache-control'] = 'private, max-age=0, no-cache'; return super.serveFile(file, stat, req, res); } else { - var ifModified = req.headers.ifModifiedSince; + var ifModified = req.headers!.ifModifiedSince; var ifRange = false; try { - ifModified = HttpDate.parse(req.headers.value('if-range')); + ifModified = HttpDate.parse(req.headers!.value('if-range')!); ifRange = true; } catch (_) { // Fail silently... @@ -97,7 +97,7 @@ class CachingVirtualDirectory extends VirtualDirectory { setCachedHeaders(stat.modified, req, res); if (useEtags && _etags.containsKey(file.absolute.path)) { - res.headers['ETag'] = _etags[file.absolute.path]; + res.headers['ETag'] = _etags[file.absolute.path]!; } if (ifRange) { @@ -120,18 +120,18 @@ class CachingVirtualDirectory extends VirtualDirectory { // If-modified didn't work; try etags if (useEtags == true) { - var etagsToMatchAgainst = req.headers['if-none-match']; + var etagsToMatchAgainst = req.headers!['if-none-match']; ifRange = false; if (etagsToMatchAgainst?.isNotEmpty != true) { - etagsToMatchAgainst = req.headers['if-range']; + etagsToMatchAgainst = req.headers!['if-range']; ifRange = etagsToMatchAgainst?.isNotEmpty == true; } if (etagsToMatchAgainst?.isNotEmpty == true) { var hasBeenModified = false; - for (var etag in etagsToMatchAgainst) { + for (var etag in etagsToMatchAgainst!) { if (etag == '*') { hasBeenModified = true; } else { @@ -166,16 +166,16 @@ class CachingVirtualDirectory extends VirtualDirectory { void setCachedHeaders( DateTime modified, RequestContext req, ResponseContext res) { - var privacy = accessLevelToString(accessLevel ?? CacheAccessLevel.PUBLIC); + var privacy = accessLevelToString(accessLevel); res.headers - ..['cache-control'] = '$privacy, max-age=${maxAge ?? 0}' + ..['cache-control'] = '$privacy, max-age=$maxAge' ..['last-modified'] = HttpDate.format(modified); - if (maxAge != null) { - var expiry = DateTime.now().add(Duration(seconds: maxAge ?? 0)); - res.headers['expires'] = HttpDate.format(expiry); - } + //if (maxAge != null) { + var expiry = DateTime.now().add(Duration(seconds: maxAge)); + res.headers['expires'] = HttpDate.format(expiry); + //} } } diff --git a/packages/static/lib/src/virtual_directory.dart b/packages/static/lib/src/virtual_directory.dart index 6642c27a..0626ca42 100644 --- a/packages/static/lib/src/virtual_directory.dart +++ b/packages/static/lib/src/virtual_directory.dart @@ -28,14 +28,14 @@ String _pathify(String path) { /// A static server plug-in. class VirtualDirectory { - String _prefix; - Directory _source; + String? _prefix; + Directory? _source; /// The directory to serve files from. - Directory get source => _source; + Directory? get source => _source; /// An optional callback to run before serving files. - final Function(File file, RequestContext req, ResponseContext res) callback; + final Function(File file, RequestContext req, ResponseContext res)? callback; final Angel app; final FileSystem fileSystem; @@ -47,7 +47,7 @@ class VirtualDirectory { final String publicPath; /// If `true` (default: `false`), then if a directory does not contain any of the specific [indexFileNames], a default directory listing will be served. - final bool allowDirectoryListing; + final bool? allowDirectoryListing; /// If `true` (default: `true`), then files will be opened as streams and piped into the request. /// @@ -55,7 +55,7 @@ class VirtualDirectory { final bool useBuffer; VirtualDirectory(this.app, this.fileSystem, - {Directory source, + {Directory? source, this.indexFileNames = const ['index.html'], this.publicPath = '/', this.callback, @@ -75,9 +75,9 @@ class VirtualDirectory { if (req.method != 'GET' && req.method != 'HEAD') { return Future.value(true); } - var path = req.uri.path.replaceAll(_straySlashes, ''); + var path = req.uri!.path.replaceAll(_straySlashes, ''); - if (_prefix?.isNotEmpty == true && !path.startsWith(_prefix)) { + if (_prefix?.isNotEmpty == true && !path.startsWith(_prefix!)) { return Future.value(true); } @@ -89,7 +89,7 @@ class VirtualDirectory { /// You can also limit this functionality to specific values of the `Accept` header, ex. `text/html`. /// If [accepts] is `null`, OR at least one of the content types in [accepts] is present, /// the view will be served. - RequestHandler pushState(String path, {Iterable accepts}) { + RequestHandler pushState(String path, {Iterable? accepts}) { var vPath = path.replaceAll(_straySlashes, ''); if (_prefix?.isNotEmpty == true) vPath = '$_prefix/$vPath'; @@ -98,7 +98,7 @@ class VirtualDirectory { if (path == vPath) return Future.value(true); if (accepts?.isNotEmpty == true) { - if (!accepts.any((x) => req.accepts(x, strict: true))) { + if (!accepts!.any((x) => req.accepts(x, strict: true))) { return Future.value(true); } } @@ -110,17 +110,17 @@ class VirtualDirectory { /// Writes the file at the given virtual [path] to a response. Future servePath( String path, RequestContext req, ResponseContext res) async { - if (_prefix.isNotEmpty) { + if (_prefix!.isNotEmpty) { // Only replace the *first* incidence // Resolve: https://github.com/angel-dart/angel/issues/41 - path = path.replaceFirst(RegExp('^' + _pathify(_prefix)), ''); + path = path.replaceFirst(RegExp('^' + _pathify(_prefix!)), ''); } if (path.isEmpty) path = '.'; path = path.replaceAll(_straySlashes, ''); - var absolute = source.absolute.uri.resolve(path).toFilePath(); - var parent = source.absolute.uri.toFilePath(); + var absolute = source!.absolute.uri.resolve(path).toFilePath(); + var parent = source!.absolute.uri.toFilePath(); if (!p.isWithin(parent, absolute) && !p.equals(parent, absolute)) { return true; @@ -199,8 +199,8 @@ class VirtualDirectory { }); for (var entity in entities) { - String stub; - String type; + String? stub; + String? type; if (entity is File) { type = '[File]'; @@ -217,10 +217,19 @@ class VirtualDirectory { } var href = stub; - if (relative.isNotEmpty) href = '/' + relative + '/' + stub; + if (relative.isNotEmpty) { + stub ??= ''; + href = '/' + relative + '/' + stub; + } - if (entity is Directory) href += '/'; - href = Uri.encodeFull(href); + if (entity is Directory) { + if (href == null) { + href = '/'; + } else { + href += '/'; + } + } + href = Uri.encodeFull(href!); res.write('
  • $type $stub
  • '); } @@ -233,11 +242,11 @@ class VirtualDirectory { } void _ensureContentTypeAllowed(String mimeType, RequestContext req) { - var value = req.headers.value('accept'); + var value = req.headers!.value('accept'); var acceptable = value == null || - value?.isNotEmpty != true || - (mimeType?.isNotEmpty == true && value?.contains(mimeType) == true) || - value?.contains('*/*') == true; + value.isNotEmpty != true || + (mimeType.isNotEmpty == true && value.contains(mimeType) == true) || + value.contains('*/*') == true; if (!acceptable) { throw AngelHttpException( UnsupportedError( @@ -253,8 +262,9 @@ class VirtualDirectory { res.headers['accept-ranges'] = 'bytes'; if (callback != null) { - return await req.app.executeHandler( - (RequestContext req, ResponseContext res) => callback(file, req, res), + return await req.app!.executeHandler( + (RequestContext req, ResponseContext res) => + callback!(file, req, res), req, res); } @@ -267,10 +277,10 @@ class VirtualDirectory { res.contentType = MediaType.parse(type); if (useBuffer == true) res.useBuffer(); - if (req.headers.value('range')?.startsWith('bytes=') != true) { + if (req.headers!.value('range')?.startsWith('bytes=') != true) { await res.streamFile(file); } else { - var header = 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 = RangeHeader(items); diff --git a/packages/static/pubspec.yaml b/packages/static/pubspec.yaml index fd1e714a..7d77dc16 100644 --- a/packages/static/pubspec.yaml +++ b/packages/static/pubspec.yaml @@ -1,8 +1,8 @@ name: angel_static description: Static server middleware for Angel. Also capable of serving Range responses. -version: 3.0.0 +version: 4.0.0 environment: - sdk: ">=2.10.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' homepage: https://github.com/angel-dart/static author: Tobe O publish_to: none @@ -12,21 +12,26 @@ dependencies: url: https://github.com/dukefirehawk/angel.git ref: sdk-2.12.x_nnbd path: packages/framework + range_header: + git: + url: https://github.com/dukefirehawk/angel.git + ref: sdk-2.12.x_nnbd + path: packages/range_header convert: ^3.0.0 - crypto: ^3.0.0 + crypto: ^3.0.1 file: ^6.1.0 http_parser: ^4.0.0 - path: ^1.4.2 - range_header: ^2.0.0 + path: ^1.8.0 + dev_dependencies: angel_test: git: url: https://github.com/dukefirehawk/angel.git ref: sdk-2.12.x_nnbd path: packages/test - http: - logging: ^1.0.0 - matcher: ^0.12.0 - pedantic: ^1.0.0 - test: ^1.15.7 + http: ^0.13.2 + logging: ^1.0.1 + matcher: ^0.12.10 + pedantic: ^1.11.0 + test: ^1.17.3 diff --git a/packages/static/test/all_test.dart b/packages/static/test/all_test.dart index 66d7af2a..28f06920 100644 --- a/packages/static/test/all_test.dart +++ b/packages/static/test/all_test.dart @@ -1,7 +1,6 @@ import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/http.dart'; import 'package:angel_static/angel_static.dart'; -import 'package:file/file.dart'; import 'package:file/local.dart'; import 'package:http/http.dart' show Client; import 'package:logging/logging.dart'; @@ -9,9 +8,9 @@ import 'package:test/test.dart'; void main() { Angel app; - AngelHttp http; + late AngelHttp http; var testDir = const LocalFileSystem().directory('test'); - String url; + late String url; var client = Client(); setUp(() async { @@ -42,7 +41,7 @@ void main() { }); tearDown(() async { - if (http.server != null) await http.server.close(force: true); + if (http.server != null) await http.server!.close(force: true); }); test('can serve files, with correct Content-Type', () async { diff --git a/packages/static/test/cache_sample.dart b/packages/static/test/cache_sample.dart index 8f9c28bd..af65bd8e 100644 --- a/packages/static/test/cache_sample.dart +++ b/packages/static/test/cache_sample.dart @@ -1,13 +1,12 @@ import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/http.dart'; import 'package:angel_static/angel_static.dart'; -import 'package:file/file.dart'; import 'package:file/local.dart'; -main() async { +void main() async { Angel app; AngelHttp http; - Directory testDir = const LocalFileSystem().directory('test'); + var testDir = const LocalFileSystem().directory('test'); app = Angel(); http = AngelHttp(app); diff --git a/packages/static/test/cache_test.dart b/packages/static/test/cache_test.dart index 9d59645e..1e944758 100644 --- a/packages/static/test/cache_test.dart +++ b/packages/static/test/cache_test.dart @@ -10,9 +10,9 @@ import 'package:test/test.dart'; void main() { Angel app; - AngelHttp http; + late AngelHttp http; var testDir = const LocalFileSystem().directory('test'); - String url; + late String url; var client = Client(); setUp(() async { @@ -42,7 +42,7 @@ void main() { }); tearDown(() async { - if (http.server != null) await http.server.close(force: true); + if (http.server != null) await http.server!.close(force: true); }); test('sets etag, cache-control, expires, last-modified', () async { diff --git a/packages/static/test/issue41_test.dart b/packages/static/test/issue41_test.dart index 4d1a766f..f9acbc2a 100644 --- a/packages/static/test/issue41_test.dart +++ b/packages/static/test/issue41_test.dart @@ -9,9 +9,9 @@ import 'package:test/test.dart'; final Directory swaggerUiDistDir = const LocalFileSystem().directory('test/node_modules/swagger-ui-dist'); -main() async { - TestClient client; - String swaggerUiCssContents, swaggerTestJsContents; +void main() async { + late TestClient client; + late String swaggerUiCssContents, swaggerTestJsContents; setUp(() async { // Load file contents diff --git a/packages/static/test/push_state_test.dart b/packages/static/test/push_state_test.dart index 4fbfba27..59d89b43 100644 --- a/packages/static/test/push_state_test.dart +++ b/packages/static/test/push_state_test.dart @@ -8,7 +8,7 @@ import 'package:test/test.dart'; void main() { Angel app; MemoryFileSystem fileSystem; - TestClient client; + late TestClient client; setUp(() async { fileSystem = MemoryFileSystem();