diff --git a/Teknik/Areas/Podcast/Controllers/PodcastController.cs b/Teknik/Areas/Podcast/Controllers/PodcastController.cs index d152d14..765d96d 100644 --- a/Teknik/Areas/Podcast/Controllers/PodcastController.cs +++ b/Teknik/Areas/Podcast/Controllers/PodcastController.cs @@ -88,8 +88,9 @@ namespace Teknik.Areas.Podcast.Controllers { if (System.IO.File.Exists(file.Path)) { + FileStream fileStream = new FileStream(file.Path, FileMode.Open, FileAccess.Read); // Read in the file - byte[] data = System.IO.File.ReadAllBytes(file.Path); + //byte[] data = System.IO.File.ReadAllBytes(file.Path); // Create File var cd = new System.Net.Mime.ContentDisposition @@ -100,7 +101,8 @@ namespace Teknik.Areas.Podcast.Controllers Response.AppendHeader("Content-Disposition", cd.ToString()); - return File(data, file.ContentType); + return new FileGenerateResult(file.FileName, file.ContentType, (response) => ResponseHelper.StreamToOutput(response, fileStream, file.ContentLength, 4 * 1024), false); + //return File(data, file.ContentType); } } } diff --git a/Teknik/Areas/Upload/Controllers/UploadController.cs b/Teknik/Areas/Upload/Controllers/UploadController.cs index 6557037..efd13dd 100644 --- a/Teknik/Areas/Upload/Controllers/UploadController.cs +++ b/Teknik/Areas/Upload/Controllers/UploadController.cs @@ -196,7 +196,6 @@ namespace Teknik.Areas.Upload.Controllers // we output the whole content? Response.AddHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + upload.ContentLength); throw new HttpException(416, "Requested Range Not Satisfiable"); - } // If the range starts with an '-' we start from the beginning @@ -272,7 +271,7 @@ namespace Teknik.Areas.Upload.Controllers return new FileGenerateResult(upload.Url, contentType, - (response) => this.DecryptStreamToOutput(response, fs, (int)length, keyBytes, ivBytes, "CTR", "NoPadding", Config.UploadConfig.ChunkSize), + (response) => ResponseHelper.DecryptStreamToOutput(response, fs, (int)length, keyBytes, ivBytes, "CTR", "NoPadding", Config.UploadConfig.ChunkSize), false); } else // Otherwise just send it @@ -280,7 +279,10 @@ namespace Teknik.Areas.Upload.Controllers // Don't buffer the response Response.Buffer = false; // Send the file - return File(fs, contentType); + return new FileGenerateResult(upload.Url, + contentType, + (response) => ResponseHelper.StreamToOutput(response, fs, (int)length, Config.UploadConfig.ChunkSize), + false); } } } @@ -291,75 +293,6 @@ namespace Teknik.Areas.Upload.Controllers return Redirect(Url.SubRouteUrl("error", "Error.Http403")); } - public void DecryptStreamToOutput(HttpResponseBase response, System.IO.Stream fileStream, int length, byte[] key, byte[] iv, string mode, string padding, int chunkSize) - { - try - { - 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 - { - 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; - } - 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(); - } - } - } - catch (HttpException httpEx) - { - 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(); - } - } - [HttpPost] [AllowAnonymous] public FileResult DownloadData(string file) diff --git a/Utilities/Utilities/ResponseHelper.cs b/Utilities/Utilities/ResponseHelper.cs new file mode 100644 index 0000000..0010158 --- /dev/null +++ b/Utilities/Utilities/ResponseHelper.cs @@ -0,0 +1,154 @@ +using Org.BouncyCastle.Crypto; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Teknik.Utilities +{ + public static class ResponseHelper + { + public static void StreamToOutput(HttpResponseBase response, Stream stream, int length, int chunkSize) + { + try + { + response.Flush(); + + int curByte = 0; + int processedBytes = 0; + byte[] buffer = new byte[chunkSize]; + int bytesRemaining = length; + int bytesToRead = chunkSize; + do + { + if (chunkSize > bytesRemaining) + { + bytesToRead = bytesRemaining; + } + + processedBytes = stream.Read(buffer, 0, bytesToRead); + if (processedBytes > 0) + { + response.OutputStream.Write(buffer, 0, processedBytes); + response.Flush(); + + // Clear the buffer + Array.Clear(buffer, 0, chunkSize); + } + curByte += processedBytes; + bytesRemaining -= processedBytes; + } + while (processedBytes > 0 && bytesRemaining > 0); + + if (bytesRemaining > 0) + { + // Clear the buffer + Array.Clear(buffer, 0, chunkSize); + + // Finalize processing of the cipher + processedBytes = stream.Read(buffer, 0, bytesToRead); + if (processedBytes > 0) + { + // We have bytes, lets write them to the output + response.OutputStream.Write(buffer, 0, processedBytes); + response.Flush(); + } + } + } + catch (HttpException httpEx) + { + // If we lost connection, that's fine + if (httpEx.ErrorCode == -2147023667) + { + // do nothing + } + else + { + throw httpEx; + } + } + catch (Exception ex) + { + throw ex; + } + finally + { + // dispose of file stream + stream.Dispose(); + } + } + + public static void DecryptStreamToOutput(HttpResponseBase response, Stream stream, int length, byte[] key, byte[] iv, string mode, string padding, int chunkSize) + { + try + { + 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 + { + if (chunkSize > bytesRemaining) + { + bytesToRead = bytesRemaining; + } + processedBytes = AES.ProcessCipherBlock(cipher, stream, 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; + } + 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(); + } + } + } + catch (HttpException httpEx) + { + // If we lost connection, that's fine + if (httpEx.ErrorCode == -2147023667) + { + // do nothing + } + else + { + throw httpEx; + } + } + catch (Exception ex) + { + throw ex; + } + finally + { + // dispose of file stream + stream.Dispose(); + } + } + } +} diff --git a/Utilities/Utilities/Utilities.csproj b/Utilities/Utilities/Utilities.csproj index 2054384..90bda44 100644 --- a/Utilities/Utilities/Utilities.csproj +++ b/Utilities/Utilities/Utilities.csproj @@ -120,6 +120,7 @@ +