serveFile method

Future<void> serveFile(
  1. EngineContext ctx,
  2. String file
)

Serves a file over HTTP.

The request parameter specifies the HTTP request. The file parameter specifies the file to serve.

Implementation

Future<void> serveFile(EngineContext ctx, String file) async {
  // removed direct request reference
  try {
    final pathContext = fileSystem.path;
    final filePath = pathContext.normalize(pathContext.join(rootPath, file));

    // Robust security check to prevent directory traversal
    if (rootPath != filePath && !pathContext.isWithin(rootPath, filePath)) {
      ctx.abortWithStatus(
        HttpStatus.forbidden,
        ctx.method == 'HEAD' ? '' : 'Access denied',
      );
      return;
    }

    final fileStat = await fileSystem.stat(filePath);

    if (fileStat.type == FileSystemEntityType.directory) {
      await serveDirectory(ctx, filePath, file);
    } else if (fileStat.type == FileSystemEntityType.file) {
      await _serveFile(ctx, filePath, fileStat);
    } else {
      ctx.abortWithStatus(
        HttpStatus.notFound,
        ctx.method == 'HEAD' ? '' : 'Not Found',
      );
    }
  } catch (e) {
    ctx.abortWithStatus(
      HttpStatus.internalServerError,
      'Internal Server Error',
    );
  }
}