Files
raven/server/AyaNova/Controllers/BackupController.cs
2018-09-04 17:37:29 +00:00

204 lines
8.7 KiB
C#

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using AyaNova.Models;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Util;
using System.Globalization;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using System.Collections.Generic;
using System.Linq;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//************************************************************************************************************** */
//JUNE 19th 2018 LARGE FILE UPLOAD POSSIBLY NEW INFO HERE:
//http://www.talkingdotnet.com/how-to-increase-file-upload-size-asp-net-core/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace AyaNova.Api.Controllers
{
//FROM DOCS HERE:
//https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#uploading-large-files-with-streaming
//https://github.com/aspnet/Docs/tree/74a44669d5e7039e2d4d2cb3f8b0c4ed742d1124/aspnetcore/mvc/models/file-uploads/sample/FileUploadSample
/// <summary>
/// Backup and restore controller for uploading or downloading backup files
/// and triggering a restore from backup
///
/// </summary>
[ApiVersion("8.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[Produces("application/json")]
[Authorize]
public class BackupController : Controller
{
private readonly AyContext ct;
private readonly ILogger<BackupController> log;
private readonly ApiServerState serverState;
/// <summary>
///
/// </summary>
/// <param name="dbcontext"></param>
/// <param name="logger"></param>
/// <param name="apiServerState"></param>
public BackupController(AyContext dbcontext, ILogger<BackupController> logger, ApiServerState apiServerState)
{
ct = dbcontext;
log = logger;
serverState = apiServerState;
}
/*
LOOKAT:
A backup archive consists of a similar format to the v7 data dumper utility, json file per object in subdirectories corresponding to object type all in a zip archive
Route to trigger restore from selected file
Route to force immediate backup
Backup code in biz objects "IBackup" interface (which in turn is probably going to implement an IExport interface as it serves dual purpose
of exporting data, or maybe that's special purpose custom objects for exporting like csv etc since there is likely a graph of data involved)
- object is exported / backed up to json
Restore code in biz objects "IRestore" interface
- object(s) imported via restore and data given to them or file or whatever (See discource project)
*/
//TODO: Copy the code from ImportAyaNova7Controller upload method instead of this old crap
// /// <summary>
// /// Upload AyaNova backup files
// /// **Files of the same name will overwrite without warning**
// /// Maximum 10gb
// /// </summary>
// /// <returns></returns>
// [HttpPost("Upload")]
// [DisableFormValueModelBinding]
// [RequestSizeLimit(10737418241)]//10737418240 = 10gb https://github.com/aspnet/Announcements/issues/267
// public async Task<IActionResult> Upload()
// {
// //Adapted from the example found here: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#uploading-large-files-with-streaming
// try
// {
// if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
// {
// return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "FileUploadAttempt", $"Expected a multipart request, but got {Request.ContentType}"));
// }
// // Used to accumulate all the form url encoded key value pairs in the
// // request.
// var formAccumulator = new KeyValueAccumulator();
// //string targetFilePath = null;
// var boundary = MultipartRequestHelper.GetBoundary(
// MediaTypeHeaderValue.Parse(Request.ContentType),
// _defaultFormOptions.MultipartBoundaryLengthLimit);
// var reader = new MultipartReader(boundary, HttpContext.Request.Body);
// var section = await reader.ReadNextSectionAsync();
// while (section != null)
// {
// ContentDispositionHeaderValue contentDisposition;
// var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
// if (hasContentDispositionHeader)
// {
// if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
// {
// //Save file
// //as it's just a backup file there is no db involvement at all
// FileUtil.storeBackupFile(section.Body, contentDisposition.FileName.Value.Replace("\"",""));
// }
// else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
// {
// // Content-Disposition: form-data; name="key"
// //
// // value
// // Do not limit the key name length here because the
// // multipart headers length limit is already in effect.
// var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
// var encoding = GetEncoding(section);
// using (var streamReader = new StreamReader(
// section.Body,
// encoding,
// detectEncodingFromByteOrderMarks: true,
// bufferSize: 1024,
// leaveOpen: true))
// {
// // The value length limit is enforced by MultipartBodyLengthLimit
// var value = await streamReader.ReadToEndAsync();
// if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
// {
// value = String.Empty;
// }
// formAccumulator.Append(key.Value, value);
// if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
// {
// throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
// }
// }
// }
// }
// // Drains any remaining section body that has not been consumed and
// // reads the headers for the next section.
// section = await reader.ReadNextSectionAsync();
// }
// }
// catch (InvalidDataException ex)
// {
// return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "FileUploadAttempt", ex.Message));
// }
// return Ok();
// }
// private static Encoding GetEncoding(MultipartSection section)
// {
// MediaTypeHeaderValue mediaType;
// var hasMediaTypeHeader = MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
// // UTF-7 is insecure and should not be honored. UTF-8 will succeed in
// // most cases.
// if (!hasMediaTypeHeader || Encoding.UTF7.Equals(mediaType.Encoding))
// {
// return Encoding.UTF8;
// }
// return mediaType.Encoding;
// }
}//eoc
}//eons