@@ -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); | |||
} | |||
} | |||
} |
@@ -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) |
@@ -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(); | |||
} | |||
} | |||
} | |||
} |
@@ -120,6 +120,7 @@ | |||
<Compile Include="ObjectHelper.cs" /> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
<Compile Include="RequestHelper.cs" /> | |||
<Compile Include="ResponseHelper.cs" /> | |||
<Compile Include="RSSFeedResult.cs" /> | |||
<Compile Include="StringExtensions.cs" /> | |||
<Compile Include="StringHelper.cs" /> |