using System.Linq; using System.Net; using ParadoxSaveParser.WebAPI.BackgroundTasks; using ParadoxSaveParser.WebAPI.HttpHelpers; namespace ParadoxSaveParser.WebAPI.Routes; public class UploadSaveHandler : RouteHandlerBase { private readonly BackgroundJobManager _bgJobManager; private readonly Dictionary _searchQueries; public UploadSaveHandler( CancellationToken cancelAllToken, BackgroundJobManager bgJobManager, Dictionary searchQueries) : base(cancelAllToken) { _bgJobManager = bgJobManager; _searchQueries = searchQueries; } public override async Task HandleRequest( HttpListenerContext ctx, ContextLogger requestLogger) { string? contentType = ctx.Request.Headers.GetValues("Content-Type")?.FirstOrDefault(); if (contentType != "application/octet-stream") return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken, new ErrorMessage(HttpStatusCode.BadRequest, $"Invalid request Content-Type: '{contentType}'") ); string saveId = Guid.NewGuid().ToString(); var metaFilePath = PathHelper.GetMetaFilePath(saveId); if (File.Exists(metaFilePath)) return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken, new ErrorMessage(HttpStatusCode.InternalServerError, $"Guid collision! file' {metaFilePath}' already exists.") ); var meta = new SaveFileMetadata { id = saveId, game = Game.EU4, status = SaveFileProcessingStatus.Initialized }; if (!Program._saveMetadataStorage.TryAdd(saveId, meta)) return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken, new ErrorMessage(HttpStatusCode.InternalServerError, $"Guid collision! Can't create metadata with id {saveId}") ); meta.status = SaveFileProcessingStatus.Uploading; var saveFilePath = PathHelper.GetSaveFilePath(meta.id); await using var saveFile = File.OpenWrite(saveFilePath); await using var remoteStream = ctx.Request.InputStream; await remoteStream.CopyToAsync(saveFile, _cancelAllToken); meta.status = SaveFileProcessingStatus.Uploaded; _bgJobManager.StartNewParsingOperation(meta, _searchQueries[meta.game], _cancelAllToken); dynamic responseData = new { saveId }; return await ReturnHelper.ResponseJson(ctx, requestLogger, _cancelAllToken, responseData); } }