Browse Source

- Added better error handling in download function.

- Fixed script passthrough to downloads.
tags/2.0.6
Teknikode 3 years ago
parent
commit
e7f02471e5

+ 64
- 52
Teknik/Areas/Upload/Controllers/UploadController.cs View File

@@ -264,19 +264,22 @@ namespace Teknik.Areas.Upload.Controllers
// Reset file stream to starting position (or start of range)
fs.Seek(startByte, SeekOrigin.Begin);

// If the IV is set, and Key is set, then decrypt it before sending
// If the IV is set, and Key is set, then decrypt it while sending
if (!string.IsNullOrEmpty(upload.Key) && !string.IsNullOrEmpty(upload.IV))
{
byte[] keyBytes = Encoding.UTF8.GetBytes(upload.Key);
byte[] ivBytes = Encoding.UTF8.GetBytes(upload.IV);

return new FileDecryptResult(upload.Url, contentType, (response) => this.GenerateExportFile(response, fs, (int)length, keyBytes, ivBytes, "CTR", "NoPadding", 4 * 1024), false);
return new FileGenerateResult(upload.Url,
contentType,
(response) => this.DecryptStreamToOutput(response, fs, (int)length, keyBytes, ivBytes, "CTR", "NoPadding", Config.UploadConfig.ChunkSize),
false);
}
else
else // Otherwise just send it
{
// Don't buffer the response
Response.Buffer = false;
// Otherwise just send it
// Send the file
return File(fs, contentType);
}
}
@@ -288,48 +291,73 @@ namespace Teknik.Areas.Upload.Controllers
return Redirect(Url.SubRouteUrl("error", "Error.Http403"));
}

public void GenerateExportFile(HttpResponseBase response, System.IO.Stream fileStream, int length, byte[] key, byte[] iv, string mode, string padding, int chunkSize)
public void DecryptStreamToOutput(HttpResponseBase response, System.IO.Stream fileStream, int length, byte[] key, byte[] iv, string mode, string padding, int chunkSize)
{
response.Flush();
IBufferedCipher cipher = AES.CreateCipher(false, key, iv, mode, padding);

int curByte = 0;
int processedBytes = 0;
byte[] buffer = new byte[chunkSize];
int bytesToRead = chunkSize;
do
try
{
if (curByte + chunkSize > length)
response.Flush();
IBufferedCipher cipher = AES.CreateCipher(false, key, iv, mode, padding);

int curByte = 0;
int processedBytes = 0;
byte[] buffer = new byte[chunkSize];
int bytesRemaining = length;
int bytesToRead = chunkSize;
do
{
bytesToRead = chunkSize - ((curByte + bytesToRead) - length);
if (chunkSize > bytesRemaining)
{
bytesToRead = bytesRemaining;
}
processedBytes = AES.ProcessCipherBlock(cipher, fileStream, bytesToRead, buffer, 0);
if (processedBytes > 0)
{
response.OutputStream.Write(buffer, 0, processedBytes);
response.Flush();

// Clear the buffer
Array.Clear(buffer, 0, chunkSize);
}
curByte += processedBytes;
bytesRemaining -= processedBytes;
}
processedBytes = AES.ProcessCipherBlock(cipher, fileStream, bytesToRead, buffer, 0);
if (processedBytes > 0)
{
response.OutputStream.Write(buffer, 0, processedBytes);
response.Flush();
while (processedBytes > 0 && bytesRemaining > 0);

if (bytesRemaining > 0)
{
// Clear the buffer
Array.Clear(buffer, 0, chunkSize);

// Finalize processing of the cipher
processedBytes = AES.FinalizeCipherBlock(cipher, buffer, 0);
if (processedBytes > 0)
{
// We have bytes, lets write them to the output
response.OutputStream.Write(buffer, 0, processedBytes);
response.Flush();
}
}
curByte += processedBytes;
}
while (processedBytes > 0 && curByte <= length);

// Clear the buffer
Array.Clear(buffer, 0, chunkSize);

// Finalize processing of the cipher
processedBytes = AES.FinalizeCipherBlock(cipher, buffer, 0);
if (processedBytes > 0)
catch (HttpException httpEx)
{
// We have bytes, lets write them to the output
response.OutputStream.Write(buffer, 0, processedBytes);
response.Flush();
if (httpEx.ErrorCode == -2147023667)
{
// do nothing
}
else
{
Logging.Logger.WriteEntry(httpEx);
}
}
catch (Exception ex)
{
Logging.Logger.WriteEntry(ex);
}
finally
{
// dispose of file stream
fileStream.Dispose();
}

// dispose of file stream
fileStream.Dispose();
}

[HttpPost]
@@ -345,24 +373,8 @@ namespace Teknik.Areas.Upload.Controllers
string filePath = Path.Combine(Config.UploadConfig.UploadDirectory, subDir, upload.FileName);
if (System.IO.File.Exists(filePath))
{
byte[] buffer;
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read

// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
sum += count; // sum is a buffer offset for next reading
}
finally
{
fileStream.Close();
}
return File(buffer, System.Net.Mime.MediaTypeNames.Application.Octet, file);
return File(fileStream, System.Net.Mime.MediaTypeNames.Application.Octet, file);
}
}
Redirect(Url.SubRouteUrl("error", "Error.Http404"));

+ 4
- 1
Teknik/Areas/Upload/Scripts/Download.js View File

@@ -45,11 +45,14 @@ function downloadFile() {
$("#progress").children('.progress-bar').html('Error Occured');
}

// Create a blob for the aes script
var scriptBlob = GenerateBlobURL(aesScriptSrc);

// Execute worker with data
var objData =
{
cmd: 'decrypt',
script: aesScriptSrc,
script: scriptBlob,
key: key,
iv: iv,
chunkSize: chunkSize,

Utilities/Utilities/FileDecryptResult.cs → Utilities/Utilities/FileGenerateResult.cs View File

@@ -13,7 +13,7 @@ namespace Teknik.Utilities
/// <summary>
/// MVC action result that generates the file content using a delegate that writes the content directly to the output stream.
/// </summary>
public class FileDecryptResult : FileResult
public class FileGenerateResult : FileResult
{
private readonly Action<HttpResponseBase> responseDelegate;

@@ -26,7 +26,7 @@ namespace Teknik.Utilities
/// <param name="contentType">Type of the content.</param>
/// <param name="content">Delegate with Stream parameter. This is the stream to which content should be written.</param>
/// <param name="bufferOutput">use output buffering. Set to false for large files to prevent OutOfMemoryException.</param>
public FileDecryptResult(string fileName, string contentType, Action<HttpResponseBase> response, bool bufferOutput)
public FileGenerateResult(string fileName, string contentType, Action<HttpResponseBase> response, bool bufferOutput)
: base(contentType)
{
if (response == null)

+ 1
- 1
Utilities/Utilities/Utilities.csproj View File

@@ -105,7 +105,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="FileDecryptResult.cs" />
<Compile Include="FileGenerateResult.cs" />
<Compile Include="HttpWebResponseResult.cs" />
<Compile Include="BundleExtensions.cs" />
<Compile Include="ByteExtensions.cs" />

Loading…
Cancel
Save