directoryTypeHandler top-level property
TypeHandler
directoryTypeHandler
Implementation
TypeHandler get directoryTypeHandler =>
TypeHandler<Directory>((req, res, Directory directory) async {
directory = directory.absolute;
final usedRoute = req.route;
String? virtualPath;
if (usedRoute.contains('*')) {
virtualPath = req.uri.path
.substring(min(req.uri.path.length, usedRoute.indexOf('*')));
}
if (req.method == 'GET' || req.method == 'HEAD') {
assert(usedRoute.contains('*'),
'TypeHandler of type Directory GET request needs a route declaration that contains a wildcard (*). Found: $usedRoute');
final filePath =
'${directory.path}/${Uri.decodeComponent(virtualPath!)}';
req.preventTraversal(filePath, directory);
req.log(() => 'Resolve virtual path: $virtualPath');
final fileCandidates = <File>[
File(filePath),
File('$filePath/index.html'),
File('$filePath/index.htm'),
];
try {
var match = fileCandidates.firstWhere((file) => file.existsSync());
req.log(() => 'Respond with file: ${match.path}');
await _respondWithFile(res, match, headerOnly: req.method == 'HEAD');
} on StateError {
req.log(() =>
'Could not match with any file. Expected file at: $filePath');
}
}
if (req.method == 'POST' || req.method == 'PUT') {
//Upload file
final body = await req.body;
if (body is Map && body['file'] is HttpBodyFileUpload) {
if (virtualPath != null) {
req.preventTraversal('${directory.path}/$virtualPath', directory);
directory = Directory('${directory.path}/$virtualPath').absolute;
}
if (await directory.exists() == false) {
await directory.create(recursive: true);
}
final fileName = (body['file'] as HttpBodyFileUpload).filename;
final fileToWrite = File('${directory.path}/$fileName');
req.preventTraversal(fileToWrite.path, directory);
await fileToWrite.writeAsBytes(
(body['file'] as HttpBodyFileUpload).content as List<int>);
final publicPath =
"${req.requestedUri.toString() + (virtualPath != null ? '/$virtualPath' : '')}/$fileName";
req.log(() => 'Uploaded file $publicPath');
await res.json({'path': publicPath});
}
}
if (req.method == 'DELETE') {
final fileToDelete =
File('${directory.path}/${Uri.decodeComponent(virtualPath!)}');
req.preventTraversal(fileToDelete.path, directory);
if (await fileToDelete.exists()) {
await fileToDelete.delete();
await res.json({'success': 'true'});
} else {
res.statusCode = 404;
await res.json({'error': 'file not found'});
}
}
});