Compare commits
1 Commits
a5f501e88e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f0b9546d4 |
@@ -78,11 +78,27 @@ public class ImageStorageService : IImageStorageService
|
||||
{
|
||||
string hex = BitConverter.ToString(headerBytes.Take(8).ToArray());
|
||||
_logger.LogWarning("Firma de archivo inválida para {Extension}: {HexBytes}", ext, hex);
|
||||
throw new Exception($"El archivo parece corrupto o tiene una firma inválida ({hex}). El sistema acepta JPG, PNG y WEBP reales.");
|
||||
throw new Exception($"El archivo parece corrupto o tiene una firma inválida ({hex}).");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 4. PREVENCIÓN DoS: Validar dimensiones sin cargar la imagen completa en memoria
|
||||
// Esto evita que una imagen de 1KB que dice ser de 50000x50000px cuelgue el servidor
|
||||
using (var stream = file.OpenReadStream())
|
||||
{
|
||||
var info = await Image.IdentifyAsync(stream);
|
||||
if (info == null) throw new Exception("No se pudo identificar el formato de la imagen.");
|
||||
|
||||
const int MaxDimension = 5000; // 5000px es más que suficiente para un aviso
|
||||
if (info.Width > MaxDimension || info.Height > MaxDimension)
|
||||
{
|
||||
_logger.LogWarning("Intento de subir imagen con dimensiones excesivas: {W}x{H}", info.Width, info.Height);
|
||||
throw new Exception($"Las dimensiones de la imagen ({info.Width}x{info.Height}) exceden el límite de seguridad de {MaxDimension}px.");
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Definir rutas
|
||||
var uploadFolder = Path.Combine(_env.WebRootPath, "uploads", "ads", adId.ToString());
|
||||
if (!Directory.Exists(uploadFolder)) Directory.CreateDirectory(uploadFolder);
|
||||
@@ -94,7 +110,7 @@ public class ImageStorageService : IImageStorageService
|
||||
var filePath = Path.Combine(uploadFolder, fileName);
|
||||
var thumbPath = Path.Combine(uploadFolder, thumbName);
|
||||
|
||||
// 2. Cargar y Procesar con ImageSharp
|
||||
// 2. Cargar y Procesar con ImageSharp (Aquí ya es seguro porque validamos dimensiones e identidad)
|
||||
using (var image = await Image.LoadAsync(file.OpenReadStream()))
|
||||
{
|
||||
// A. Guardar imagen principal (Optimized: Max width 1280px)
|
||||
@@ -102,22 +118,21 @@ public class ImageStorageService : IImageStorageService
|
||||
{
|
||||
image.Mutate(x => x.Resize(new ResizeOptions
|
||||
{
|
||||
Size = new Size(1280, 0), // 0 mantiene aspect ratio
|
||||
Size = new Size(1280, 0),
|
||||
Mode = ResizeMode.Max
|
||||
}));
|
||||
}
|
||||
await image.SaveAsJpegAsync(filePath);
|
||||
|
||||
// B. Generar Thumbnail (Max width 400px para grillas)
|
||||
// B. Generar Thumbnail
|
||||
image.Mutate(x => x.Resize(new ResizeOptions
|
||||
{
|
||||
Size = new Size(400, 300),
|
||||
Mode = ResizeMode.Crop // Recorte inteligente para que queden parejitas
|
||||
Mode = ResizeMode.Crop
|
||||
}));
|
||||
await image.SaveAsJpegAsync(thumbPath);
|
||||
}
|
||||
|
||||
// Retornar ruta relativa web de la imagen principal
|
||||
return $"/uploads/ads/{adId}/{fileName}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user