Breaking changes ;)
This commit is contained in:
parent
8fc27551fa
commit
196f79af94
3 changed files with 66 additions and 61 deletions
|
@ -25,13 +25,7 @@ import 'package:angel_static/angel_static.dart';
|
||||||
|
|
||||||
main() async {
|
main() async {
|
||||||
final app = new Angel();
|
final app = new Angel();
|
||||||
|
await app.configure(new VirtualDirectory(source: new Directory('./public')));
|
||||||
app.mount('/virtual', new VirtualDirectory(
|
|
||||||
source: new Directory('./foo/bar'),
|
|
||||||
publicPath: '/virtual'));
|
|
||||||
|
|
||||||
app.mount('/', new VirtualDirectory(source: new Directory('./public')));
|
|
||||||
|
|
||||||
await app.startServer();
|
await app.startServer();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
|
import 'package:angel_route/angel_route.dart';
|
||||||
import 'package:mime/mime.dart' show lookupMimeType;
|
import 'package:mime/mime.dart' show lookupMimeType;
|
||||||
|
|
||||||
final RegExp _param = new RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?');
|
final RegExp _param = new RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?');
|
||||||
|
@ -22,7 +23,9 @@ String _pathify(String path) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
class VirtualDirectory extends Router {
|
class VirtualDirectory {
|
||||||
|
final bool debug;
|
||||||
|
String _prefix;
|
||||||
Directory _source;
|
Directory _source;
|
||||||
Directory get source => _source;
|
Directory get source => _source;
|
||||||
final List<String> indexFileNames;
|
final List<String> indexFileNames;
|
||||||
|
@ -30,10 +33,11 @@ class VirtualDirectory extends Router {
|
||||||
|
|
||||||
VirtualDirectory(
|
VirtualDirectory(
|
||||||
{Directory source,
|
{Directory source,
|
||||||
bool debug: false,
|
this.debug: false,
|
||||||
this.indexFileNames: const ['index.html'],
|
this.indexFileNames: const ['index.html'],
|
||||||
this.publicPath: '/'})
|
this.publicPath: '/'}) {
|
||||||
: super(debug: debug) {
|
_prefix = publicPath.replaceAll(_straySlashes, '');
|
||||||
|
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
_source = source;
|
_source = source;
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,16 +46,42 @@ class VirtualDirectory extends Router {
|
||||||
: './web';
|
: './web';
|
||||||
_source = new Directory(dirPath);
|
_source = new Directory(dirPath);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final prefix = publicPath.replaceAll(_straySlashes, '');
|
_printDebug(msg) {
|
||||||
|
if (debug) print(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
call(AngelBase app) async => serve(app);
|
||||||
|
|
||||||
|
Future<bool> sendFile(File file, ResponseContext res) async {
|
||||||
|
_printDebug('Streaming file ${file.absolute.path}...');
|
||||||
|
res
|
||||||
|
..willCloseItself = true
|
||||||
|
..header(HttpHeaders.CONTENT_TYPE, lookupMimeType(file.path))
|
||||||
|
..status(200);
|
||||||
|
await res.streamFile(file);
|
||||||
|
await res.io.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serve(Router router) {
|
||||||
_printDebug('Source directory: ${source.absolute.path}');
|
_printDebug('Source directory: ${source.absolute.path}');
|
||||||
_printDebug('Public path prefix: "$prefix"');
|
_printDebug('Public path prefix: "$_prefix"');
|
||||||
|
|
||||||
get('*', (RequestContext req, ResponseContext res) async {
|
handler(RequestContext req, ResponseContext res) async {
|
||||||
var path = req.path.replaceAll(_straySlashes, '');
|
var path = req.path.replaceAll(_straySlashes, '');
|
||||||
|
|
||||||
if (prefix.isNotEmpty) {
|
return serveFile(path, res);
|
||||||
path = path.replaceAll(new RegExp('^' + _pathify(prefix)), '');
|
}
|
||||||
|
|
||||||
|
router.get('$publicPath/*', handler);
|
||||||
|
router.get(publicPath, (req, res) => serveFile('', res));
|
||||||
|
}
|
||||||
|
|
||||||
|
serveFile(String path, ResponseContext res) async {
|
||||||
|
if (_prefix.isNotEmpty) {
|
||||||
|
path = path.replaceAll(new RegExp('^' + _pathify(_prefix)), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
final file = new File.fromUri(source.absolute.uri.resolve(path));
|
final file = new File.fromUri(source.absolute.uri.resolve(path));
|
||||||
|
@ -74,21 +104,5 @@ class VirtualDirectory extends Router {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_printDebug(msg) {
|
|
||||||
if (debug) print(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> sendFile(File file, ResponseContext res) async {
|
|
||||||
_printDebug('Streaming file ${file.absolute.path}...');
|
|
||||||
res
|
|
||||||
..willCloseItself = true
|
|
||||||
..header(HttpHeaders.CONTENT_TYPE, lookupMimeType(file.path))
|
|
||||||
..status(200);
|
|
||||||
await res.streamFile(file);
|
|
||||||
await res.underlyingResponse.close();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,34 +11,31 @@ main() {
|
||||||
Client client = new Client();
|
Client client = new Client();
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
app = new Angel();
|
app = new Angel(debug: true);
|
||||||
|
|
||||||
app.mount(
|
await app.configure(new VirtualDirectory(
|
||||||
'/virtual',
|
|
||||||
new VirtualDirectory(
|
|
||||||
debug: true,
|
debug: true,
|
||||||
source: testDir,
|
source: testDir,
|
||||||
publicPath: '/virtual',
|
publicPath: '/virtual',
|
||||||
indexFileNames: ['index.txt']));
|
indexFileNames: ['index.txt']));
|
||||||
|
|
||||||
app.mount(
|
await app.configure(new VirtualDirectory(
|
||||||
'/',
|
|
||||||
new VirtualDirectory(
|
|
||||||
debug: true,
|
debug: true,
|
||||||
source: testDir,
|
source: testDir,
|
||||||
indexFileNames: ['index.php', 'index.txt']));
|
indexFileNames: ['index.php', 'index.txt']));
|
||||||
|
|
||||||
app.get('*', 'Fallback');
|
app.get('*', 'Fallback');
|
||||||
|
|
||||||
app
|
app
|
||||||
..normalize()
|
..normalize()
|
||||||
..dumpTree();
|
..dumpTree(showMatchers: true);
|
||||||
|
|
||||||
await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
||||||
url = "http://${app.httpServer.address.host}:${app.httpServer.port}";
|
url = "http://${app.httpServer.address.host}:${app.httpServer.port}";
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await app.httpServer.close(force: true);
|
if (app.httpServer != null) await app.httpServer.close(force: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can serve files, with correct Content-Type', () async {
|
test('can serve files, with correct Content-Type', () async {
|
||||||
|
|
Loading…
Reference in a new issue