From cceabd3c7d250764ce39f8a2171cdf3a764e234a Mon Sep 17 00:00:00 2001 From: Tobe O Date: Mon, 9 Jul 2018 13:38:22 -0400 Subject: [PATCH] Dart 2 fixes + bump version + allow buffering --- CHANGELOG.md | 4 ++++ analysis_options.yaml | 3 ++- example/main.dart | 3 ++- lib/src/cache.dart | 10 +++++----- lib/src/virtual_directory.dart | 35 ++++++++++++++++++++++------------ pubspec.yaml | 5 +++-- test/all_test.dart | 7 +++++-- test/cache_sample.dart | 4 +++- test/cache_test.dart | 6 ++++-- 9 files changed, 51 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0871ace9..80f84867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.3.0+1 +* Dart 2 fixes. +* Enable optionally writing responses to the buffer instead of streaming. + # 1.3.0 * `pushState` uses `strict` mode when `accepts` is passed. diff --git a/analysis_options.yaml b/analysis_options.yaml index 518eb901..eae1e42a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,2 +1,3 @@ analyzer: - strong-mode: true \ No newline at end of file + strong-mode: + implicit-casts: false \ No newline at end of file diff --git a/example/main.dart b/example/main.dart index fd606cf7..593f2551 100644 --- a/example/main.dart +++ b/example/main.dart @@ -4,6 +4,7 @@ import 'package:file/local.dart'; main() async { var app = new Angel(); + var http = new AngelHttp(app); var fs = const LocalFileSystem(); var vDir = new VirtualDirectory( app, @@ -13,6 +14,6 @@ main() async { ); app.use(vDir.handleRequest); - var server = await app.startServer('127.0.0.1', 3000); + var server = await http.startServer('127.0.0.1', 3000); print('Listening at http://${server.address.address}:${server.port}'); } diff --git a/lib/src/cache.dart b/lib/src/cache.dart index 5982e08a..4dc7020a 100644 --- a/lib/src/cache.dart +++ b/lib/src/cache.dart @@ -1,8 +1,6 @@ import 'dart:async'; -import 'dart:convert'; -import 'dart:typed_data'; import 'package:angel_framework/angel_framework.dart'; -import 'package:async/async.dart'; +import 'package:dart2_constant/convert.dart'; import 'package:file/file.dart'; import 'package:intl/intl.dart'; import 'package:mime/mime.dart'; @@ -15,7 +13,7 @@ String formatDateForHttp(DateTime dt) => _fmt.format(dt.toUtc()) + ' GMT'; /// Generates a weak ETag from the given buffer. String weakEtag(List buf) { - return 'W/${buf.length}' + BASE64URL.encode(buf.take(50).toList()); + return 'W/${buf.length}' + base64Url.encode(buf.take(50).toList()); } /// Returns a string representation of the given [CacheAccessLevel]. @@ -61,6 +59,7 @@ class CachingVirtualDirectory extends VirtualDirectory { this.onlyInProduction: false, this.useEtags: true, bool allowDirectoryListing, + bool useStream, String publicPath, callback(File file, RequestContext req, ResponseContext res)}) : super(app, fileSystem, @@ -68,7 +67,8 @@ class CachingVirtualDirectory extends VirtualDirectory { indexFileNames: indexFileNames ?? ['index.html'], publicPath: publicPath ?? '/', callback: callback, - allowDirectoryListing: allowDirectoryListing); + allowDirectoryListing: allowDirectoryListing, + useStream: useStream); @override Future serveFile( diff --git a/lib/src/virtual_directory.dart b/lib/src/virtual_directory.dart index dc2a5f2e..8c795753 100644 --- a/lib/src/virtual_directory.dart +++ b/lib/src/virtual_directory.dart @@ -46,12 +46,18 @@ class VirtualDirectory { /// 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; + /// If `true` (default: `true`), then files will be opened as streams and piped into the request. + /// + /// If not, the response buffer will be used instead. + final bool useStream; + VirtualDirectory(this.app, this.fileSystem, {Directory source, this.indexFileNames: const ['index.html'], this.publicPath: '/', this.callback, - this.allowDirectoryListing: false}) { + this.allowDirectoryListing: false, + this.useStream: true}) { _prefix = publicPath.replaceAll(_straySlashes, ''); if (source != null) { _source = source; @@ -86,7 +92,8 @@ class VirtualDirectory { if (path == vPath) return new Future.value(true); if (accepts?.isNotEmpty == true) { - if (!accepts.any((x) => req.accepts(x, strict: true))) return new Future.value(true); + if (!accepts.any((x) => req.accepts(x, strict: true))) + return new Future.value(true); } return servePath(vPath, req, res); @@ -111,8 +118,8 @@ class VirtualDirectory { } /// Writes the file at the path given by the [stat] to a response. - Future serveStat(String absolute, String relative, FileStat stat, RequestContext req, - ResponseContext res) async { + Future serveStat(String absolute, String relative, FileStat stat, + RequestContext req, ResponseContext res) async { if (stat.type == FileSystemEntityType.DIRECTORY) return await serveDirectory( fileSystem.directory(absolute), relative, stat, req, res); @@ -126,8 +133,8 @@ class VirtualDirectory { } /// Serves the index file of a [directory], if it exists. - Future serveDirectory(Directory directory, String relative, FileStat stat, - RequestContext req, ResponseContext res) async { + Future serveDirectory(Directory directory, String relative, + FileStat stat, RequestContext req, ResponseContext res) async { for (String indexFileName in indexFileNames) { final index = fileSystem.file(directory.absolute.uri.resolve(indexFileName)); @@ -177,11 +184,9 @@ class VirtualDirectory { type = '[Directory]'; else if (entity is Link) type = '[Link]'; - if (relative.isNotEmpty) - href = '/' + relative + '/' + stub; + if (relative.isNotEmpty) href = '/' + relative + '/' + stub; - if (entity is Directory) - href += '/'; + if (entity is Directory) href += '/'; res.write('
  • $type $stub
  • '); } @@ -215,14 +220,20 @@ class VirtualDirectory { if (callback != null) { var r = callback(file, req, res); r = r is Future ? await r : r; - if (r != null && r != true) return r; + return r == true; + //if (r != null && r != true) return r; } var type = lookupMimeType(file.path) ?? 'application/octet-stream'; _ensureContentTypeAllowed(type, req); res.headers['content-type'] = type; - await file.openRead().pipe(res); + if (useStream != true) { + res.buffer.add(await file.readAsBytes()); + } else { + await file.openRead().pipe(res); + } + return false; } } diff --git a/pubspec.yaml b/pubspec.yaml index 10bf1f72..8265af4a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,13 @@ name: angel_static description: Static server middleware for Angel. environment: - sdk: ">=1.19.0" + sdk: ">=1.8.0 <3.0.0" homepage: https://github.com/angel-dart/static author: Tobe O -version: 1.3.0 +version: 1.3.0+1 dependencies: angel_framework: ^1.1.0-alpha + dart2_constant: ^1.0.0 file: ^2.0.0 intl: ">=0.0.0 <1.0.0" mime: ^0.9.3 diff --git a/test/all_test.dart b/test/all_test.dart index c01c3def..5178ffc3 100644 --- a/test/all_test.dart +++ b/test/all_test.dart @@ -8,12 +8,14 @@ import 'package:test/test.dart'; main() { Angel app; + AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); String url; Client client = new Client(); setUp(() async { app = new Angel(); + http = new AngelHttp(app); app.logger = new Logger('angel')..onRecord.listen(print); app.use( @@ -26,6 +28,7 @@ main() { app.use( new VirtualDirectory(app, const LocalFileSystem(), source: testDir, + useStream: false, indexFileNames: ['index.php', 'index.txt']).handleRequest, ); @@ -33,12 +36,12 @@ main() { app.dumpTree(showMatchers: true); - var server = await app.startServer(); + var server = await http.startServer(); url = "http://${server.address.host}:${server.port}"; }); tearDown(() async { - if (app.httpServer != null) await app.httpServer.close(force: true); + if (http.httpServer != null) await http.httpServer.close(force: true); }); test('can serve files, with correct Content-Type', () async { diff --git a/test/cache_sample.dart b/test/cache_sample.dart index 6a6e0dc7..86f0e09a 100644 --- a/test/cache_sample.dart +++ b/test/cache_sample.dart @@ -5,8 +5,10 @@ import 'package:file/local.dart'; main() async { Angel app; + AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); app = new Angel(); + http = new AngelHttp(app); app.use( new CachingVirtualDirectory(app, const LocalFileSystem(), @@ -20,6 +22,6 @@ main() async { app.dumpTree(showMatchers: true); - var server = await app.startServer(); + var server = await http.startServer(); print('Open at http://${server.address.host}:${server.port}'); } diff --git a/test/cache_test.dart b/test/cache_test.dart index d2c4de9d..285e01a2 100644 --- a/test/cache_test.dart +++ b/test/cache_test.dart @@ -9,12 +9,14 @@ import 'package:test/test.dart'; main() { Angel app; + AngelHttp http; Directory testDir = const LocalFileSystem().directory('test'); String url; Client client = new Client(); setUp(() async { app = new Angel(); + http = new AngelHttp(app); app.use( new CachingVirtualDirectory(app, const LocalFileSystem(), @@ -34,12 +36,12 @@ main() { if (rec.stackTrace != null) print(rec.stackTrace); }); - var server = await app.startServer(); + var server = await http.startServer(); url = "http://${server.address.host}:${server.port}"; }); tearDown(() async { - if (app.httpServer != null) await app.httpServer.close(force: true); + if (http.httpServer != null) await http.httpServer.close(force: true); }); test('sets etag, cache-control, expires, last-modified', () async {