handler method
Request handler.
Register this request handler with the server's pipeline using a pattern with a single wildcard pattern. That path parameter will be used as the relative path underneath the baseDir to find the file or directory.
Implementation
Future<Response> handler(Request req) async {
assert(_baseDir != null);
assert(_baseDir.isNotEmpty);
// Get the relative path
final values = req.pathParams.values("*");
if (values.isEmpty) {
throw new ArgumentError("Static file handler registered with no *");
} else if (1 < values.length) {
throw new ArgumentError("Static file handler registered with multiple *");
}
final components = values[0].split("/");
var depth = 0;
while (0 <= depth && depth < components.length) {
final c = components[depth];
if (c == "..") {
components.removeAt(depth);
depth--;
if (depth < 0) {
if (throwNotFoundExceptions) {
// tried to climb above base directory
throw new NotFoundException(NotFoundException.foundStaticHandler);
} else {
return null;
}
}
} else if (c == ".") {
components.removeAt(depth);
} else if (c.isEmpty && depth != components.length - 1) {
components.removeAt(depth); // keep last "" to indicate dir listing
} else {
depth++;
}
}
final path = "$_baseDir/${components.join("/")}";
_logStaticFiles.finer("[${req.id}] static file/directory requested: $path");
if (!path.endsWith("/")) {
// Probably a file
final file = new File(path);
if (file.existsSync()) {
_logStaticFiles.finest("[${req.id}] static file found: $path");
return await _serveFile(req, file);
} else if (allowFilePathsAsDirectories &&
await new Directory(path).exists()) {
// A directory exists with the same name
if (allowDirectoryListing || await _findDefaultFile("$path/") != null) {
// Can tell the browser to treat it as a directory
// Note: must change URL in browser, otherwise relative links break
_logStaticFiles.finest("[${req.id}] treating as static directory");
return new ResponseRedirect("${req.requestPath}/");
}
} else {
_logStaticFiles.finest("[${req.id}] static file not found");
}
} else {
// Request for a directory
final dir = new Directory(path);
if (await dir.exists()) {
// Try to find one of the default files in that directory
final defaultFile = await _findDefaultFile(path);
if (defaultFile != null) {
_logStaticFiles.finest(
"[${req.id}] static directory: default file found: $defaultFile");
return await _serveFile(req, defaultFile);
}
if (allowDirectoryListing) {
// List the contents of the directory
_logStaticFiles.finest("[${req.id}] returning directory listing");
final notTop = (1 < components.length);
return await directoryListing(req, dir, linkToParent: notTop);
} else {
_logStaticFiles
.finest("[${req.id}] static directory listing not allowed");
}
} else {
_logStaticFiles.finest("[${req.id}] static directory not found");
}
}
// Not found (or directory listing not allowed)
if (throwNotFoundExceptions) {
throw new NotFoundException(NotFoundException.foundStaticHandler);
} else {
return null;
}
}