createStaticHandler function
Creates a Shelf handler for serving static files.
Example
final app = Router();
// Serve compiled assets from build/web
app.mount('/', createStaticHandler('build/web'));
// Or with configuration
app.mount('/', createStaticHandler(
'build/web',
config: StaticHandlerConfig(
path: 'build/web',
enableCaching: true,
maxAge: 86400,
),
));
Implementation
Handler createStaticHandler(String path, {StaticHandlerConfig? config}) {
config ??= StaticHandlerConfig(path: path);
return (Request request) async {
var filePath = request.url.path;
// Remove leading slash if present
if (filePath.startsWith('/')) {
filePath = filePath.substring(1);
}
// Construct full file path
final fullPath = filePath.isEmpty
? config!.path
: '${config!.path}/$filePath';
// Check for directory traversal attacks
final normalizedPath = File(fullPath).absolute.path;
final basePath = Directory(config.path).absolute.path;
if (!normalizedPath.startsWith(basePath)) {
return Response.forbidden('Access denied');
}
final file = File(fullPath);
final dir = Directory(fullPath);
// Handle directory requests
if (await dir.exists()) {
if (config.defaultFile != null) {
final defaultFile = File('$fullPath/${config.defaultFile}');
if (await defaultFile.exists()) {
return _serveFile(defaultFile, config, request);
}
}
if (config.listDirectories) {
return _listDirectory(dir, filePath);
}
return Response.notFound('Not found');
}
// Handle file requests
if (await file.exists()) {
return _serveFile(file, config, request);
}
return Response.notFound('Not found');
};
}