Refactor authentication and streaming cookie handling: implement secure cookie logic based on environment in AuthEndpoints and StreamingEndpoints, enhance rate limiting policy in Program.cs, and update logging configuration in appsettings.json. Fix validation behavior to use asynchronous validation methods and improve error handling in frontend components.
This commit is contained in:
@@ -10,10 +10,19 @@ public sealed class ImageDownloader(IHttpClientFactory httpFactory) : IImageDown
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// Пускаем только абсолютные http/https URL: URL приходит из ответа metadata-провайдера
|
||||
// (постеры TMDb/OMDb), и скомпрометированный/подменённый ответ не должен заставить сервер
|
||||
// дёрнуть file://, ftp:// или иную схему.
|
||||
if (
|
||||
!Uri.TryCreate(url, UriKind.Absolute, out var uri)
|
||||
|| (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
|
||||
)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var client = httpFactory.CreateClient("metadata");
|
||||
using var response = await client.GetAsync(url, cancellationToken);
|
||||
using var response = await client.GetAsync(uri, cancellationToken);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ public sealed class InboxScannerBackgroundService(
|
||||
private readonly MediaOptions _media = mediaOptions.Value;
|
||||
private readonly Dictionary<string, long> _lastSizes = new(StringComparer.Ordinal);
|
||||
|
||||
// Файлы, регистрация которых стабильно отклоняется командой (например, неподдерживаемый контейнер):
|
||||
// помечаем, чтобы не пытаться регистрировать их заново каждые два тика и не засорять лог. Забываются,
|
||||
// когда файл исчезает из inbox (тогда одноимённый новый файл снова получит попытку).
|
||||
private readonly HashSet<string> _failed = new(StringComparer.Ordinal);
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
paths.EnsureDirectories();
|
||||
@@ -67,6 +72,9 @@ public sealed class InboxScannerBackgroundService(
|
||||
var name = Path.GetFileName(path);
|
||||
present.Add(name);
|
||||
|
||||
if (_failed.Contains(name))
|
||||
continue; // уже пытались и получили отказ — ждём, пока файл уберут/заменят
|
||||
|
||||
long size;
|
||||
try
|
||||
{
|
||||
@@ -89,16 +97,20 @@ public sealed class InboxScannerBackgroundService(
|
||||
continue;
|
||||
}
|
||||
|
||||
await RegisterAsync(name, cancellationToken);
|
||||
var registered = await RegisterAsync(name, cancellationToken);
|
||||
_lastSizes.Remove(name);
|
||||
if (!registered)
|
||||
_failed.Add(name); // команда отклонила файл — больше не пытаемся, пока он в inbox
|
||||
}
|
||||
|
||||
// Забываем исчезнувшие файлы, чтобы словарь не рос.
|
||||
// Забываем исчезнувшие файлы, чтобы словари не росли (и одноимённый новый файл снова попробовался).
|
||||
foreach (var stale in _lastSizes.Keys.Where(k => !present.Contains(k)).ToList())
|
||||
_lastSizes.Remove(stale);
|
||||
foreach (var stale in _failed.Where(k => !present.Contains(k)).ToList())
|
||||
_failed.Remove(stale);
|
||||
}
|
||||
|
||||
private async Task RegisterAsync(string fileName, CancellationToken cancellationToken)
|
||||
private async Task<bool> RegisterAsync(string fileName, CancellationToken cancellationToken)
|
||||
{
|
||||
await using var scope = scopeFactory.CreateAsyncScope();
|
||||
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
|
||||
@@ -116,14 +128,14 @@ public sealed class InboxScannerBackgroundService(
|
||||
result.Value,
|
||||
fileName
|
||||
);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning(
|
||||
"Не удалось зарегистрировать {File} из inbox: {Error}",
|
||||
fileName,
|
||||
result.Error.Code
|
||||
);
|
||||
}
|
||||
|
||||
logger.LogWarning(
|
||||
"Не удалось зарегистрировать {File} из inbox: {Error}",
|
||||
fileName,
|
||||
result.Error.Code
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user