diff --git a/src/DnsmasqWebUI/Controllers/StatusController.cs b/src/DnsmasqWebUI/Controllers/StatusController.cs
index f95af13..a942cb2 100644
--- a/src/DnsmasqWebUI/Controllers/StatusController.cs
+++ b/src/DnsmasqWebUI/Controllers/StatusController.cs
@@ -163,32 +163,39 @@ public class StatusController : ControllerBase
/// Returns the full log file from the path in effective config (log-facility). Untruncated.
[HttpGet("logs/download")]
- public async Task GetLogsDownload(CancellationToken ct)
+ public Task GetLogsDownload(CancellationToken ct)
{
var (effectiveConfig, _) = _configSetService.GetEffectiveConfigWithSources();
var logsPath = EffectiveDnsmasqConfig.GetLogsPath(effectiveConfig);
if (string.IsNullOrEmpty(logsPath))
- return NotFound();
+ return Task.FromResult(NotFound());
try
{
+ ct.ThrowIfCancellationRequested();
_logger.LogDebug("Get status logs download");
var fullPath = Path.IsPathRooted(logsPath) ? Path.GetFullPath(logsPath) : Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), logsPath));
if (!System.IO.File.Exists(fullPath))
- return NotFound();
+ return Task.FromResult(NotFound());
- var content = await System.IO.File.ReadAllTextAsync(fullPath, System.Text.Encoding.UTF8, ct);
var fileName = Path.GetFileName(fullPath);
if (string.IsNullOrEmpty(fileName)) fileName = "dnsmasq.log";
- return File(
- System.Text.Encoding.UTF8.GetBytes(content),
- "text/plain",
- fileName);
+
+ // ReadAllTextAsync pre-allocates from Length; concurrent log writes can grow the file mid-read
+ // and trigger ArgumentOutOfRangeException. Stream with FileShare.ReadWrite and stream the response.
+ var stream = new FileStream(
+ fullPath,
+ FileMode.Open,
+ FileAccess.Read,
+ FileShare.ReadWrite | FileShare.Delete,
+ bufferSize: 64 * 1024,
+ FileOptions.Asynchronous | FileOptions.SequentialScan);
+ return Task.FromResult(File(stream, "text/plain; charset=utf-8", fileName));
}
catch (Exception ex)
{
_logger.LogError(ex, "Status logs download failed");
- return StatusCode(500, new { error = ex.Message });
+ return Task.FromResult(StatusCode(500, new { error = ex.Message }));
}
}
}
diff --git a/src/DnsmasqWebUI/DnsmasqWebUI.csproj b/src/DnsmasqWebUI/DnsmasqWebUI.csproj
index 8d3485b..0625a2a 100644
--- a/src/DnsmasqWebUI/DnsmasqWebUI.csproj
+++ b/src/DnsmasqWebUI/DnsmasqWebUI.csproj
@@ -3,7 +3,7 @@
net10.0
enable
- 0.0.9
+ 0.0.10
enable
true