-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #47 from skttl/our-self-host
Adds our-self-host
Showing
10 changed files
with
556 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Options; | ||
using Moq; | ||
using NUnit.Framework; | ||
using Our.Umbraco.TagHelpers.Configuration; | ||
using Our.Umbraco.TagHelpers.Services; | ||
using System; | ||
using Umbraco.Cms.Core.Cache; | ||
using Umbraco.Cms.Core.Logging; | ||
|
||
namespace Our.Umbraco.TagHelpers.Tests | ||
{ | ||
public class SelfHostServiceTests | ||
{ | ||
private Mock<IProfilingLogger> _loggerMock; | ||
private Mock<IAppPolicyCache> _runtimeCacheMock; | ||
private Mock<IWebHostEnvironment> _hostingEnvironmentMock; | ||
private Mock<IOptions<OurUmbracoTagHelpersConfiguration>> _globalSettingsMock; | ||
private SelfHostService _service; | ||
|
||
[SetUp] | ||
public void SetUp() | ||
{ | ||
_loggerMock = new Mock<IProfilingLogger>(); | ||
_runtimeCacheMock = new Mock<IAppPolicyCache>(); | ||
_hostingEnvironmentMock = new Mock<IWebHostEnvironment>(); | ||
_globalSettingsMock = new Mock<IOptions<OurUmbracoTagHelpersConfiguration>>(); | ||
_globalSettingsMock.SetupGet(x => x.Value).Returns(new OurUmbracoTagHelpersConfiguration | ||
{ | ||
OurSelfHost = new SelfHostTagHelperConfiguration | ||
{ | ||
RootFolder = "/self-hosted/" | ||
} | ||
}); | ||
_service = new SelfHostService( | ||
_loggerMock.Object, | ||
_runtimeCacheMock.Object, | ||
_hostingEnvironmentMock.Object, | ||
_globalSettingsMock.Object | ||
); | ||
} | ||
|
||
[Test] | ||
public void GetRemoteFolderPath_GivenUriWithMoreThanTwoSegments_ReturnsFolderPath() | ||
{ | ||
// Arrange | ||
var uri = new Uri("http://www.example.com/folder/subfolder/file.jpg"); | ||
var expectedFolderPath = "/folder/subfolder"; | ||
|
||
// Act | ||
var result = _service.GetRemoteFolderPath(uri); | ||
|
||
// Assert | ||
Assert.AreEqual(expectedFolderPath, result); | ||
} | ||
|
||
[Test] | ||
public void GetRemoteFolderPath_GivenUriWithLessThanTwoSegments_ReturnsEmptyString() | ||
{ | ||
// Arrange | ||
var uri = new Uri("http://www.example.com/"); | ||
var expectedFolderPath = string.Empty; | ||
|
||
// Act | ||
var result = _service.GetRemoteFolderPath(uri); | ||
|
||
// Assert | ||
Assert.AreEqual(expectedFolderPath, result); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
using Microsoft.AspNetCore.Razor.TagHelpers; | ||
using Moq; | ||
using NUnit.Framework; | ||
using Our.Umbraco.TagHelpers.Models; | ||
using Our.Umbraco.TagHelpers.Services; | ||
using Our.Umbraco.TagHelpers.Tests.Helpers; | ||
using System.Threading.Tasks; | ||
|
||
namespace Our.Umbraco.TagHelpers.Tests | ||
{ | ||
[TestFixture] | ||
public class SelfHostTagHelperTests | ||
{ | ||
[Test] | ||
public async Task ProcessAsync_SrcAttribute_SetsSrcAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.jpg" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.SrcAttribute = "https://example.com/test.jpg"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("img", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.AreEqual("/media/test.jpg", output.Attributes["src"].Value); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_HrefAttribute_SetsHrefAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.pdf" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.HrefAttribute = "https://example.com/test.pdf"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("a", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.AreEqual("/media/test.pdf", output.Attributes["href"].Value); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_RemovesOurSelfHostAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.jpg" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.SrcAttribute = "https://example.com/test.jpg"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("img", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.IsFalse(output.Attributes.ContainsName("our-self-host")); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_RemovesFolderAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.jpg" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.SrcAttribute = "https://example.com/test.jpg"; | ||
tagHelper.FolderName = "test-folder"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("img", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.IsFalse(output.Attributes.ContainsName("folder")); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_RemovesExtAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.jpg" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.SrcAttribute = "https://example.com/test"; | ||
tagHelper.Extension = "jpg"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("img", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.IsFalse(output.Attributes.ContainsName("ext")); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_SrcAttribute_EnforcesExtAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.jpg" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.SrcAttribute = "https://example.com/test"; | ||
tagHelper.Extension = "jpg"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("img", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.IsTrue(output.Attributes.ContainsName("src") && output.Attributes["src"].Value.ToString().EndsWith(tagHelper.Extension)); | ||
} | ||
|
||
[Test] | ||
public async Task ProcessAsync_HrefAttribute_EnforcesExtAttribute() | ||
{ | ||
// Arrange | ||
var selfHostServiceMock = new Mock<ISelfHostService>(); | ||
selfHostServiceMock.Setup(x => x.SelfHostFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) | ||
.ReturnsAsync(new SelfHostedFile { Url = "/media/test.pdf" }); | ||
|
||
var tagHelper = new SelfHostTagHelper(selfHostServiceMock.Object); | ||
tagHelper.HrefAttribute = "https://example.com/test"; | ||
tagHelper.Extension = "pdf"; | ||
var id = "unique-id"; | ||
var tagHelperContext = TestContextHelpers.GetTagHelperContext(id); | ||
var output = new TagHelperOutput("a", new TagHelperAttributeList(), (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent())); | ||
|
||
// Act | ||
await tagHelper.ProcessAsync(tagHelperContext, output); | ||
|
||
// Assert | ||
Assert.IsTrue(output.Attributes.ContainsName("href") && output.Attributes["href"].Value.ToString().EndsWith(tagHelper.Extension)); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
Our.Umbraco.TagHelpers/Composing/SelfHostServiceComposer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Our.Umbraco.TagHelpers.Services; | ||
using Umbraco.Cms.Core.Composing; | ||
using Umbraco.Cms.Core.DependencyInjection; | ||
|
||
namespace Our.Umbraco.TagHelpers.Composing | ||
{ | ||
public class SelfHostServiceComposer : IComposer | ||
{ | ||
public void Compose(IUmbracoBuilder builder) | ||
{ | ||
builder.Services.AddSingleton<ISelfHostService, SelfHostService>(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
Our.Umbraco.TagHelpers/Extensions/WebHostEnvironmentExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using System; | ||
using System.IO; | ||
using Umbraco.Cms.Core; | ||
|
||
namespace Our.Umbraco.TagHelpers.Extensions | ||
{ | ||
[Obsolete("This should be removed, when the package gets upgraded past Umbraco 10")] | ||
public static class WebHostEnvironmentExtensions | ||
{ | ||
|
||
/// <summary> | ||
/// Maps a virtual path to a physical path to the application's web root | ||
/// </summary> | ||
/// <remarks> | ||
/// Depending on the runtime 'web root', this result can vary. For example in Net Framework the web root and the | ||
/// content root are the same, however | ||
/// in netcore the web root is /wwwroot therefore this will Map to a physical path within wwwroot. | ||
/// </remarks> | ||
|
||
[Obsolete("This should be removed, when the package gets upgraded past Umbraco 10")] | ||
public static string MapPathWebRoot(this IWebHostEnvironment webHostEnvironment, string path) | ||
{ | ||
var root = webHostEnvironment.WebRootPath; | ||
|
||
// Create if missing | ||
if (string.IsNullOrWhiteSpace(root)) | ||
{ | ||
root = webHostEnvironment.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"); | ||
} | ||
|
||
var newPath = path.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); | ||
|
||
// TODO: This is a temporary error because we switched from IOHelper.MapPath to HostingEnvironment.MapPathXXX | ||
// IOHelper would check if the path passed in started with the root, and not prepend the root again if it did, | ||
// however if you are requesting a path be mapped, it should always assume the path is relative to the root, not | ||
// absolute in the file system. This error will help us find and fix improper uses, and should be removed once | ||
// all those uses have been found and fixed | ||
if (newPath.StartsWith(root)) | ||
{ | ||
throw new ArgumentException( | ||
"The path appears to already be fully qualified. Please remove the call to MapPathWebRoot"); | ||
} | ||
|
||
return Path.Combine(root, newPath.TrimStart(Constants.CharArrays.TildeForwardSlashBackSlash)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace Our.Umbraco.TagHelpers.Models | ||
{ | ||
public class SelfHostedFile | ||
{ | ||
public string? ExternalUrl { get; set; } | ||
public string? FileName { get; set; } | ||
public string? FolderPath { get; set; } | ||
public string? Url { get; set; } | ||
|
||
public override string? ToString() | ||
{ | ||
return Url; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using Microsoft.AspNetCore.Razor.TagHelpers; | ||
using Our.Umbraco.TagHelpers.Services; | ||
using System.Threading.Tasks; | ||
using Umbraco.Extensions; | ||
|
||
namespace Our.Umbraco.TagHelpers | ||
{ | ||
/// <summary> | ||
/// Downloads the specified file (in href or src) to wwwroot and changes the link to local. | ||
/// </summary> | ||
[HtmlTargetElement("*", Attributes = "our-self-host")] | ||
public class SelfHostTagHelper : TagHelper | ||
{ | ||
private readonly ISelfHostService _selfHostService; | ||
|
||
public SelfHostTagHelper(ISelfHostService selfHostService) | ||
{ | ||
_selfHostService = selfHostService; | ||
} | ||
|
||
[HtmlAttributeName("folder")] | ||
public string? FolderName { get; set; } | ||
[HtmlAttributeName("src")] | ||
public string? SrcAttribute { get; set; } | ||
[HtmlAttributeName("href")] | ||
public string? HrefAttribute { get; set; } | ||
[HtmlAttributeName("ext")] | ||
public string? Extension { get; set; } | ||
public string Url => SrcAttribute.IfNullOrWhiteSpace(HrefAttribute); | ||
|
||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) | ||
{ | ||
var url = (Url.StartsWith("//") ? $"https:{Url}" : Url); | ||
var selfHostedFile = await _selfHostService.SelfHostFile(url, FolderName, Extension); | ||
|
||
if (SrcAttribute.IsNullOrWhiteSpace() == false) | ||
{ | ||
output.Attributes.SetAttribute("data-original-src", SrcAttribute); | ||
output.Attributes.SetAttribute("src", selfHostedFile.Url); | ||
} | ||
else if (HrefAttribute.IsNullOrWhiteSpace() == false) | ||
{ | ||
output.Attributes.SetAttribute("data-original-href", HrefAttribute); | ||
output.Attributes.SetAttribute("href", selfHostedFile.Url); | ||
} | ||
|
||
output.Attributes.Remove(new TagHelperAttribute("our-self-host")); | ||
output.Attributes.Remove(new TagHelperAttribute("folder")); | ||
output.Attributes.Remove(new TagHelperAttribute("ext")); | ||
} | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Our.Umbraco.TagHelpers.Models; | ||
using System.Threading.Tasks; | ||
|
||
namespace Our.Umbraco.TagHelpers.Services | ||
{ | ||
public interface ISelfHostService | ||
{ | ||
Task<SelfHostedFile> SelfHostFile(string url, string? subfolder = null, string? fileExtension = null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Options; | ||
using Our.Umbraco.TagHelpers.Configuration; | ||
using Our.Umbraco.TagHelpers.Extensions; | ||
using Our.Umbraco.TagHelpers.Models; | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Umbraco.Cms.Core.Cache; | ||
using Umbraco.Cms.Core.Logging; | ||
using Umbraco.Extensions; | ||
|
||
namespace Our.Umbraco.TagHelpers.Services | ||
{ | ||
public class SelfHostService : ISelfHostService | ||
{ | ||
private readonly IProfilingLogger _logger; | ||
private readonly IAppPolicyCache _runtimeCache; | ||
private readonly IWebHostEnvironment _hostingEnvironment; | ||
private readonly OurUmbracoTagHelpersConfiguration _globalSettings; | ||
|
||
public SelfHostService( | ||
IProfilingLogger logger, | ||
IAppPolicyCache appPolicyCache, | ||
IWebHostEnvironment hostingEnvironment, | ||
IOptions<OurUmbracoTagHelpersConfiguration> globalSettings | ||
) | ||
{ | ||
_logger = logger; | ||
_runtimeCache = appPolicyCache; | ||
_hostingEnvironment = hostingEnvironment; | ||
_globalSettings = globalSettings.Value; | ||
} | ||
|
||
public async Task<SelfHostedFile> SelfHostFile(string url, string? subfolder = null, string? fileExtension = null) | ||
{ | ||
return await _runtimeCache.GetCacheItem($"Our.Umbraco.TagHelpers.Services.SelfHostService.SelfHostedFile({url}, {subfolder}, {fileExtension})", async () => | ||
{ | ||
using (_logger.TraceDuration<ISelfHostService>($"Start generating SelfHostedFile: {url}", $"Finished generating SelfHostedFile: {url}")) | ||
{ | ||
var uri = new Uri(url, UriKind.Absolute); | ||
|
||
var selfHostedFile = new SelfHostedFile() | ||
{ | ||
ExternalUrl = url, | ||
FileName = uri.Segments.Last() + fileExtension.IfNotNull(ext => ext.EnsureStartsWith(".")), | ||
FolderPath = GetFolderPath(uri, subfolder) | ||
}; | ||
|
||
selfHostedFile.Url = await GetSelfHostedUrl(selfHostedFile); | ||
return selfHostedFile; | ||
} | ||
}); | ||
} | ||
|
||
public string GetFolderPath(Uri uri, string? subfolder = null) | ||
{ | ||
var folderPath = _globalSettings.OurSelfHost.RootFolder; | ||
|
||
if (subfolder.IsNullOrWhiteSpace() == false) folderPath += subfolder.EnsureStartsWith("/"); | ||
|
||
folderPath += GetRemoteFolderPath(uri); | ||
|
||
return folderPath; | ||
} | ||
|
||
public string GetRemoteFolderPath(Uri uri) | ||
{ | ||
var segments = uri?.Segments; | ||
|
||
// if there is more than 2 segments (first segment is the root, last segment is the file) | ||
// we can extract the folderpath | ||
if (segments?.Length > 2) | ||
{ | ||
segments = segments.Skip(1).SkipLast(1).ToArray(); | ||
|
||
// remove trailing slash from segments | ||
segments = segments.Select(x => x.Replace("/", "")).ToArray(); | ||
|
||
// join segments with slash | ||
return string.Join("/", segments).EnsureStartsWith("/"); | ||
} | ||
|
||
return string.Empty; | ||
} | ||
private async Task<string> GetSelfHostedUrl(SelfHostedFile file) | ||
{ | ||
var filePath = $"{file.FolderPath}/{file.FileName}"; | ||
var localPath = _hostingEnvironment.MapPathWebRoot(file.FolderPath); | ||
var localFilePath = _hostingEnvironment.MapPathWebRoot(filePath); | ||
|
||
if (!File.Exists(localFilePath) && file.ExternalUrl is not null) | ||
{ | ||
using (_logger.TraceDuration<ISelfHostService>($"Start downloading SelfHostedFile: {file.ExternalUrl} to {localFilePath}", $"Finished downloading SelfHostedFile: {file.ExternalUrl} to {localFilePath}")) | ||
{ | ||
var content = await GetUrlContent(file.ExternalUrl); | ||
if (content != null) | ||
{ | ||
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath); | ||
await File.WriteAllBytesAsync(localFilePath, content); | ||
return filePath; | ||
} | ||
else | ||
{ | ||
return file.ExternalUrl; | ||
} | ||
} | ||
} | ||
|
||
return filePath; | ||
} | ||
|
||
private static async Task<byte[]?> GetUrlContent(string url) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
using (var result = await client.GetAsync(url)) | ||
{ | ||
if (result is not null && result.IsSuccessStatusCode) | ||
{ | ||
return await result.Content.ReadAsByteArrayAsync(); | ||
} | ||
else | ||
{ | ||
return null; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters