1.3.0-alpha
This commit is contained in:
parent
393c4bff02
commit
3f2c29571b
6 changed files with 71 additions and 54 deletions
10
README.md
10
README.md
|
@ -9,25 +9,27 @@ In `pubspec.yaml`:
|
|||
|
||||
```yaml
|
||||
dependencies:
|
||||
angel_static: ^1.3.0
|
||||
angel_static: ^1.3.0-alpha
|
||||
```
|
||||
|
||||
# Usage
|
||||
To serve files from a directory, you need to create a `VirtualDirectory`.
|
||||
Keep in mind that `angel_static` uses `package:file` instead of `dart:io`.
|
||||
|
||||
```dart
|
||||
import 'dart:io';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_static/angel_static.dart';
|
||||
import 'package:file/local.dart';
|
||||
|
||||
main() async {
|
||||
var app = new Angel();
|
||||
var fs = const LocalFileSystem();
|
||||
|
||||
// Normal static server
|
||||
var vDir = new VirtualDirectory(source: new Directory('./public'));
|
||||
var vDir = new VirtualDirectory(app, fs, source: new Directory('./public'));
|
||||
|
||||
// Send Cache-Control, ETag, etc. as well
|
||||
var vDir = new CachingVirtualDirectory(source: new Directory('./public'));
|
||||
var vDir = new CachingVirtualDirectory(app, fs, source: new Directory('./public'));
|
||||
|
||||
// Mount the VirtualDirectory's request handler
|
||||
app.use(vDir.handleRequest);
|
||||
|
|
|
@ -128,38 +128,16 @@ class CachingVirtualDirectory extends VirtualDirectory {
|
|||
}
|
||||
}
|
||||
|
||||
var queue = new StreamQueue(file.openRead());
|
||||
|
||||
return new Future<bool>(() async {
|
||||
var buf = new Uint8List(50), hanging = <int>[];
|
||||
int added = 0;
|
||||
|
||||
while (added < 50) {
|
||||
var deficit = 50 - added;
|
||||
var next = await queue.next;
|
||||
|
||||
for (int i = 0; i < deficit; i++) {
|
||||
buf[added + i] = next[i];
|
||||
}
|
||||
|
||||
if (next.length > deficit) {
|
||||
hanging.addAll(next.skip(deficit));
|
||||
}
|
||||
}
|
||||
|
||||
return file.readAsBytes().then((buf) {
|
||||
var etag = _etags[file.absolute.path] = weakEtag(buf);
|
||||
|
||||
res.statusCode = 200;
|
||||
res.headers
|
||||
..['ETag'] = etag
|
||||
..['content-type'] =
|
||||
lookupMimeType(file.path) ?? 'application/octet-stream';
|
||||
setCachedHeaders(stat.modified, req, res);
|
||||
|
||||
res.add(buf);
|
||||
res.add(hanging);
|
||||
|
||||
return queue.rest.pipe(res).then((_) => false);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ dependencies:
|
|||
mime: ^0.9.3
|
||||
path: ^1.4.2
|
||||
dev_dependencies:
|
||||
angel_test: ^1.0.0
|
||||
angel_test: ^1.1.0-alpha
|
||||
http: ^0.11.3
|
||||
mustache4dart: ^1.1.0
|
||||
test: ^0.12.13
|
||||
|
|
|
@ -75,28 +75,4 @@ main() {
|
|||
});
|
||||
expect(response.body, equals("index!"));
|
||||
});
|
||||
|
||||
test('can gzip: just gzip', () async {
|
||||
var response = await client
|
||||
.get("$url/sample.txt", headers: {'accept-encoding': 'gzip'});
|
||||
expect(response.body, equals("Hello world"));
|
||||
expect(response.headers['content-type'], contains("text/plain"));
|
||||
expect(response.headers['content-encoding'], 'gzip');
|
||||
});
|
||||
|
||||
test('can gzip: wildcard', () async {
|
||||
var response = await client
|
||||
.get("$url/sample.txt", headers: {'accept-encoding': 'foo, *'});
|
||||
expect(response.body, equals("Hello world"));
|
||||
expect(response.headers['content-type'], contains("text/plain"));
|
||||
expect(response.headers['content-encoding'], 'gzip');
|
||||
});
|
||||
|
||||
test('can gzip: gzip and friends', () async {
|
||||
var response = await client.get("$url/sample.txt",
|
||||
headers: {'accept-encoding': 'gzip, deflate, br'});
|
||||
expect(response.body, equals("Hello world"));
|
||||
expect(response.headers['content-type'], contains("text/plain"));
|
||||
expect(response.headers['content-encoding'], 'gzip');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ 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';
|
||||
import 'package:matcher/matcher.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
@ -26,6 +27,13 @@ main() {
|
|||
|
||||
app.dumpTree(showMatchers: true);
|
||||
|
||||
app.logger = new Logger('angel_static')
|
||||
..onRecord.listen((rec) {
|
||||
print(rec);
|
||||
if (rec.error != null) print(rec.error);
|
||||
if (rec.stackTrace != null) print(rec.stackTrace);
|
||||
});
|
||||
|
||||
var server = await app.startServer();
|
||||
url = "http://${server.address.host}:${server.port}";
|
||||
});
|
||||
|
@ -43,7 +51,7 @@ main() {
|
|||
|
||||
expect(response.statusCode, equals(200));
|
||||
expect(
|
||||
['ETag', 'cache-control', 'expires', 'last-modified'],
|
||||
['etag', 'cache-control', 'expires', 'last-modified'],
|
||||
everyElement(predicate(
|
||||
response.headers.containsKey, 'contained in response headers')));
|
||||
});
|
||||
|
|
53
test/push_state_test.dart
Normal file
53
test/push_state_test.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_static/angel_static.dart';
|
||||
import 'package:angel_test/angel_test.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() {
|
||||
Angel app;
|
||||
MemoryFileSystem fileSystem;
|
||||
TestClient client;
|
||||
|
||||
setUp(() async {
|
||||
fileSystem = new MemoryFileSystem();
|
||||
|
||||
var webDir = fileSystem.directory('web');
|
||||
await webDir.create(recursive: true);
|
||||
|
||||
var indexFile = webDir.childFile('index.html');
|
||||
await indexFile.writeAsString('index');
|
||||
|
||||
app = new Angel();
|
||||
|
||||
var vDir = new VirtualDirectory(
|
||||
app,
|
||||
fileSystem,
|
||||
source: webDir,
|
||||
);
|
||||
|
||||
app
|
||||
..use(vDir.handleRequest)
|
||||
..use(vDir.pushState('index.html'))
|
||||
..use('Fallback');
|
||||
|
||||
app.logger = new Logger('push_state')
|
||||
..onRecord.listen(
|
||||
(rec) {
|
||||
print(rec);
|
||||
if (rec.error != null) print(rec.error);
|
||||
if (rec.stackTrace != null) print(rec.stackTrace);
|
||||
},
|
||||
);
|
||||
|
||||
client = await connectTo(app);
|
||||
});
|
||||
|
||||
tearDown(() => client.close());
|
||||
|
||||
test('serves as fallback', () async {
|
||||
var response = await client.get('/nope');
|
||||
expect(response.body, 'index');
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue