Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions LearningHub.Nhs.WebUI/Controllers/Api/ResourceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public async Task<IActionResult> DownloadResource(string filePath, string fileNa
}

var file = await this.fileService.DownloadFileAsync(filePath, fileName);

if (file != null)
{
return this.File(file.Content, file.ContentType, fileName);
return !string.IsNullOrEmpty(file.DownloadUrl) ? this.Redirect(file.DownloadUrl) : this.File(file.Content, file.ContentType, fileName);
}
else
{
Expand Down Expand Up @@ -106,7 +107,8 @@ public async Task<IActionResult> DownloadResourceAndRecordActivity(int resourceV
ActivityStatus = ActivityStatusEnum.Completed,
};
await this.activityService.CreateResourceActivityAsync(activity);
return this.File(file.Content, file.ContentType, fileName);

return !string.IsNullOrEmpty(file.DownloadUrl) ? this.Redirect(file.DownloadUrl) : this.File(file.Content, file.ContentType, fileName);
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions LearningHub.Nhs.WebUI/Models/FileDownloadResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,10 @@ public class FileDownloadResponse
/// Gets or sets the ContentType.
/// </summary>
public long ContentLength { get; set; }

/// <summary>
/// Gets or sets when downloading large files, a SAS URL is returned so the client can download directly from Azure Files.
/// </summary>
public string DownloadUrl { get; set; }
}
}
51 changes: 29 additions & 22 deletions LearningHub.Nhs.WebUI/Services/FileService.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
namespace LearningHub.Nhs.WebUI.Services
{
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using Azure;
using Azure.Storage;
using Azure.Storage.Files.Shares;
using Azure.Storage.Files.Shares.Models;
using Azure.Storage.Sas;
using LearningHub.Nhs.Models.Resource;
using LearningHub.Nhs.WebUI.Configuration;
using LearningHub.Nhs.WebUI.Interfaces;
Expand Down Expand Up @@ -145,26 +141,19 @@ public async Task<FileDownloadResponse> DownloadFileAsync(string filePath, strin

try
{
if (fileSize <= 900 * 1024 * 1024)
var response = new FileDownloadResponse
{
// Directly download the entire file as a stream
var response = await file.DownloadAsync();
return new FileDownloadResponse
{
Content = response.Value.Content,
ContentType = properties.Value.ContentType,
ContentLength = fileSize,
};
}
else
ContentType = properties.Value.ContentType,
ContentLength = fileSize,
Content = await file.OpenReadAsync(),
};

if (fileSize >= 999 * 1024 * 1024)
{
return new FileDownloadResponse
{
Content = await file.OpenReadAsync(),
ContentType = properties.Value.ContentType,
ContentLength = fileSize,
};
response.DownloadUrl = this.GenerateSasUriForFile(file);
}

return response;
}
catch (Exception ex)
{
Expand Down Expand Up @@ -460,5 +449,23 @@ private async Task<ShareFileClient> FindFileAsync(string filePath, string fileNa

return null;
}

private string GenerateSasUriForFile(ShareFileClient fileClient)
{
if (fileClient.CanGenerateSasUri)
{
ShareSasBuilder sasBuilder = new ShareSasBuilder(ShareFileSasPermissions.Read, DateTimeOffset.UtcNow.AddMinutes(20))
{
Protocol = SasProtocol.Https,
};

Uri sasUri = fileClient.GenerateSasUri(sasBuilder);
return sasUri.ToString();
}
else
{
throw new InvalidOperationException("Unable to generate SAS URI for the file.");
}
}
}
}
Loading