Files
2021-12-07 18:28:04 +01:00

99 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
[ApiController]
[Route("[controller]")]
public class FilesaveController : ControllerBase
{
private readonly IWebHostEnvironment env;
private readonly ILogger<FilesaveController> logger;
public FilesaveController(IWebHostEnvironment env,
ILogger<FilesaveController> logger)
{
this.env = env;
this.logger = logger;
}
[HttpPost]
public async Task<ActionResult<IList<UploadResult>>> PostFile(
[FromForm] IEnumerable<IFormFile> files)
{
var maxAllowedFiles = 3;
long maxFileSize = 1024 * 1024 * 15;
var filesProcessed = 0;
var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/");
List<UploadResult> uploadResults = new();
foreach (var file in files)
{
var uploadResult = new UploadResult();
string trustedFileNameForFileStorage;
var untrustedFileName = file.FileName;
uploadResult.FileName = untrustedFileName;
var trustedFileNameForDisplay =
WebUtility.HtmlEncode(untrustedFileName);
if (filesProcessed < maxAllowedFiles)
{
if (file.Length == 0)
{
logger.LogInformation("{FileName} length is 0 (Err: 1)",
trustedFileNameForDisplay);
uploadResult.ErrorCode = 1;
}
else if (file.Length > maxFileSize)
{
logger.LogInformation("{FileName} of {Length} bytes is " +
"larger than the limit of {Limit} bytes (Err: 2)",
trustedFileNameForDisplay, file.Length, maxFileSize);
uploadResult.ErrorCode = 2;
}
else
{
try
{
trustedFileNameForFileStorage = Path.GetRandomFileName();
var path = Path.Combine(env.ContentRootPath,
env.EnvironmentName, "unsafe_uploads",
trustedFileNameForFileStorage);
await using FileStream fs = new(path, FileMode.Create);
await file.CopyToAsync(fs);
logger.LogInformation("{FileName} saved at {Path}",
trustedFileNameForDisplay, path);
uploadResult.Uploaded = true;
uploadResult.StoredFileName = trustedFileNameForFileStorage;
}
catch (IOException ex)
{
logger.LogError("{FileName} error on upload (Err: 3): {Message}",
trustedFileNameForDisplay, ex.Message);
uploadResult.ErrorCode = 3;
}
}
filesProcessed++;
}
else
{
logger.LogInformation("{FileName} not uploaded because the " +
"request exceeded the allowed {Count} of files (Err: 4)",
trustedFileNameForDisplay, maxAllowedFiles);
uploadResult.ErrorCode = 4;
}
uploadResults.Add(uploadResult);
}
return new CreatedResult(resourcePath, uploadResults);
}
}