dvAdminAsset function
The file under root that path, a request path under mount, names.
The mount itself is index.html, and a path under it that is no file is
the shell too: the admin is one application with its own routes. Null
when the path tries to leave root or there is no shell to fall back to.
Implementation
DVAdminAsset? dvAdminAsset(String root, DVAdminMount mount, String path) {
final String rest = path.substring(mount.path.length);
final String relative =
rest.isEmpty || rest == '/' ? 'index.html' : rest.substring(1);
// Decoded before it is checked, so %2e%2e is the same two dots here as it
// is to any proxy in front of this. An invalid escape is not a filename.
final String decoded;
try {
decoded = Uri.decodeComponent(relative).replaceAll(r'\', '/');
} on ArgumentError {
return null;
}
final List<String> segments = <String>[];
for (final String segment in decoded.split('/')) {
if (segment.isEmpty || segment == '.') continue;
// Refused rather than resolved. A dot-dot that stays inside the root is
// still a request nobody's dashboard makes.
if (segment == '..' || segment.contains(':')) return null;
segments.add(segment);
}
if (decoded.startsWith('/')) return null;
final String separator = Platform.pathSeparator;
final File asset = File(<String>[root, ...segments].join(separator));
if (segments.isNotEmpty && asset.existsSync()) {
return DVAdminAsset(
asset.readAsBytesSync(), dvAdminContentType(segments.last));
}
final File shell = File('$root${separator}index.html');
if (!shell.existsSync()) return null;
return DVAdminAsset(shell.readAsBytesSync(), 'text/html; charset=utf-8');
}