Skip to content

Commit

Permalink
Merge pull request #678 from noopman/cdnsupport
Browse files Browse the repository at this point in the history
Adding CDN support for binary content. Configurable via the Admin page
  • Loading branch information
poppastring authored Jan 18, 2023
2 parents ddb8c8d + 8e715df commit 3331d8d
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 22 deletions.
7 changes: 5 additions & 2 deletions source/DasBlog.Services/ConfigFile/Interfaces/ISiteConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ public interface ISiteConfig

string Root { get; set; }

string Copyright { get; set; }
string CdnFrom { get; set; }
string CdnTo { get; set; }

int RssDayCount { get; set; }
string Copyright { get; set; }

int RssDayCount { get; set; }

int RssMainEntryCount { get; set; }

Expand Down
7 changes: 6 additions & 1 deletion source/DasBlog.Services/ConfigFile/SiteConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ namespace DasBlog.Services.ConfigFile
public class SiteConfig : ISiteConfig
{
private string _root;
private string _cdnFrom;
private string _cdnTo;

public SiteConfig() { }
public SiteConfig() { }

public string Title { get; set; }
public string Subtitle { get; set; }
Expand All @@ -77,6 +79,9 @@ public string Root {
}
}
}
public string CdnFrom { get; set; }
public string CdnTo { get; set; }

public string AllowedHosts { get; set; }
public string Copyright { get; set; }
public int RssDayCount { get; set; }
Expand Down
5 changes: 2 additions & 3 deletions source/DasBlog.Tests/UnitTests/SiteConfigTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using DasBlog.Services.ConfigFile.Interfaces;
using newtelligence.DasBlog.Runtime;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace DasBlog.Tests.UnitTests
Expand All @@ -17,10 +15,11 @@ public class SiteConfigTest : ISiteConfig
public string Description { get => "Description"; set => throw new NotImplementedException(); }
public string Contact { get => "Contact"; set => throw new NotImplementedException(); }
public string Root { get => "http://www.poppastring.com/"; set => throw new NotImplementedException(); }
public string CdnFrom{ get => ""; set => throw new NotImplementedException(); }
public string CdnTo{ get => ""; set => throw new NotImplementedException(); }
public string Copyright { get => "CopyRight"; set => throw new NotImplementedException(); }
public int RssDayCount { get => 100; set => throw new NotImplementedException(); }
public bool ShowCommentCount { get => true; set => throw new NotImplementedException(); }

public int RssMainEntryCount { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public int RssEntryCount { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public bool EnableRssItemFooters { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
Expand Down
5 changes: 3 additions & 2 deletions source/DasBlog.Web.Repositories/FileSystemBinaryManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using DasBlog.Managers.Interfaces;
using DasBlog.Services;
using DasBlog.Services.ConfigFile;
using DasBlog.Services.ConfigFile.Interfaces;
using DasBlog.Services.FileManagement;
using DasBlog.Services.FileManagement.Interfaces;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -36,7 +35,9 @@ public FileSystemBinaryManager(IDasBlogSettings dasBlogSettings, IConfigFileServ

var loggingDataService = LoggingDataServiceFactory.GetService(Path.Combine(dasBlogSettings.WebRootDirectory, dasBlogSettings.SiteConfiguration.LogDir));

this.binaryDataService = BinaryDataServiceFactory.GetService(options.BinaryFolder, physBinaryPathUrl, loggingDataService);
var cdnManager = CdnManagerFactory.GetService(dasBlogSettings.SiteConfiguration.CdnFrom, dasBlogSettings.SiteConfiguration.CdnTo);

binaryDataService = BinaryDataServiceFactory.GetService(options.BinaryFolder, physBinaryPathUrl, loggingDataService, cdnManager);
}

public string SaveFile(Stream inputFile, string fileName)
Expand Down
10 changes: 10 additions & 0 deletions source/DasBlog.Web.UI/Config/site.config
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@
<LogDir>logs</LogDir>
<BinariesDir>content/binary</BinariesDir>

<!-- OPTIONAL: Content Delivery Network (CDN)
The two CDN settings below (CdnFrom/CdnTo) is a search and replace pattern.
* Default binaries storage is <Root>/<BinariesDir>.
* Note: This setting will not work from localhost when posting a new blog post.
-->
<!-- The part of your <Root>/<BinariesDir> hosting path you want to replace (ex. http://example.com/content/binary/): -->
<CdnFrom></CdnFrom>
<!-- The URL of the cdn servcie you are replacing to (ex. http://cdn.example.com/content/binary/): -->
<CdnTo></CdnTo>

<EnableTitlePermaLink>true</EnableTitlePermaLink>
<EnableTitlePermaLinkUnique>false</EnableTitlePermaLinkUnique>
<EnableTitlePermaLinkSpaces>false</EnableTitlePermaLinkSpaces>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,16 @@ public class SiteViewModel

[DisplayName("Time zone index")]
[Description("")]

public int DisplayTimeZoneIndex { get; set; }

[DisplayName("CDN from")]
[Description("The part of your Root URL to replace with the CDN URL. (optional)")]
public string CdnFrom { get; set; }

[DisplayName("CDN to")]
[Description("The CDN URL that will replace 'CDN from'. (optional)")]
public string CdnTo { get; set; }

[DisplayName("Comments require approval")]
[Description("")]
public bool CommentsRequireApproval { get; set; }
Expand Down
16 changes: 16 additions & 0 deletions source/DasBlog.Web.UI/Views/Admin/Settings.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,22 @@
@Html.ValidationMessageFor(m => m.SiteConfig.DisplayTimeZoneIndex, null, new { @class = "text-danger" })

</div>

<div class="form-group row mb-3">

@Html.LabelFor(m => @Model.SiteConfig.CdnFrom, null, new { @class = "col-form-label col-sm-2" })
<div class="col-sm-5">
@Html.TextBoxFor(m => @Model.SiteConfig.CdnFrom, null, new { @class = "form-control sm-10" })
</div>
@Html.ValidationMessageFor(m => m.SiteConfig.CdnFrom, null, new { @class = "text-danger" })

@Html.LabelFor(m => @Model.SiteConfig.CdnTo, null, new { @class = "col-form-label col-sm-2" })
<div class="col-sm-5">
@Html.TextBoxFor(m => @Model.SiteConfig.CdnTo, null, new { @class = "form-control sm-10" })
</div>
@Html.ValidationMessageFor(m => m.SiteConfig.CdnTo, null, new { @class = "text-danger" })

</div>

<h3>Security</h3>

Expand Down
35 changes: 35 additions & 0 deletions source/newtelligence.DasBlog.Runtime/CdnManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;

namespace newtelligence.DasBlog.Runtime
{
public static class CdnManagerFactory
{
public static ICdnManager GetService(string cdnFrom, string cdnTo)
{
return new CdnManager(cdnFrom, cdnTo);
}
}

internal sealed class CdnManager : ICdnManager
{
private readonly string cdnFrom;
private readonly string cdnTo;

/// <summary>
/// Setting up the cdn manager to return cdn uris when that is configured.
/// </summary>
/// <param name="cdnFrom">The binary hosting path to be replaced.</param>
/// <param name="cdnTo">The cdn binary hosting path to change to.</param>
public CdnManager(string cdnFrom, string cdnTo)
{
this.cdnFrom = string.IsNullOrWhiteSpace(cdnFrom) ? null : cdnFrom;
this.cdnTo = string.IsNullOrWhiteSpace(cdnTo) || this.cdnFrom == null ? null : cdnTo;
}

public string ApplyCdnUri(string uri)
{
// If the cdnUri is null then we can just return the uri.
return cdnTo == null ? uri : uri.Replace(cdnFrom, cdnTo);
}
}
}
29 changes: 16 additions & 13 deletions source/newtelligence.DasBlog.Runtime/FileSystemBinaryDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ public static class BinaryDataServiceFactory
/// </summary>
/// <param name="contentLocation"></param>
/// <returns></returns>
public static IBinaryDataService GetService(string contentLocation, Uri rootUrl, ILoggingDataService loggingService)
public static IBinaryDataService GetService(string contentLocation, Uri rootUrl, ILoggingDataService loggingService, ICdnManager cdnManager)
{
IBinaryDataService service;

lock (serviceLock)
{
if (!services.TryGetValue(contentLocation, out service))
{
service = new FileSystemBinaryDataService(contentLocation, rootUrl, loggingService);
service = new FileSystemBinaryDataService(contentLocation, rootUrl, loggingService, cdnManager);
services.Add(contentLocation, service);
}
}
Expand All @@ -50,14 +50,14 @@ public static bool RemoveService(string contentLocation)

internal sealed class FileSystemBinaryDataService : IBinaryDataService
{

/// <summary>
///
/// </summary>
/// <param name="contentLocation">The location of the content on disk.</param>
/// <param name="binaryRelativeUrl">The relative url to the binary content from the root of the site.</param>
/// <param name="loggingService">The logging service.</param>
internal FileSystemBinaryDataService(string contentLocation, Uri binaryRootUrl, ILoggingDataService loggingService)
/// <summary>
///
/// </summary>
/// <param name="contentLocation">The location of the content on disk.</param>
/// <param name="binaryRootUrl">The relative url to the binary content from the root of the site.</param>
/// <param name="loggingService">The logging service.</param>
/// <param name="cdnManager">Creates content URis for CDN locations.</param>
internal FileSystemBinaryDataService(string contentLocation, Uri binaryRootUrl, ILoggingDataService loggingService, ICdnManager cdnManager)
{
// parameter validation
if (string.IsNullOrEmpty(contentLocation))
Expand All @@ -82,6 +82,7 @@ internal FileSystemBinaryDataService(string contentLocation, Uri binaryRootUrl,

this.contentLocation = contentLocation;
this.loggingService = loggingService;
this.cdnManager = cdnManager;
this.binaryRoot = binaryRootUrl;
}

Expand Down Expand Up @@ -144,9 +145,11 @@ public string SaveFile(System.IO.Stream inputFile, ref string fileName)

string absUri = GetAbsoluteFileUri(file.FullName, out relUri);

fileName = relUri;
fileName = relUri;

absUri = cdnManager.ApplyCdnUri(absUri);

return absUri;
return absUri;
}

private string GetAbsoluteFileUri(string fullPath, out string relFileUri)
Expand Down Expand Up @@ -218,6 +221,6 @@ private bool EqualBuffers(byte[] buf1, byte[] buf2)
private string contentLocation;
private Uri binaryRoot;
private ILoggingDataService loggingService;

private readonly ICdnManager cdnManager;
}
}
16 changes: 16 additions & 0 deletions source/newtelligence.DasBlog.Runtime/ICdnManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace newtelligence.DasBlog.Runtime
{
/// <summary>
/// When the site is configured with a "CdnRoot" setting,
/// this manager is used to create content URIs for the CDN location.
/// </summary>
public interface ICdnManager
{
/// <summary>
/// Manages URI creation for resources when CDN is configured.
/// </summary>
/// <param name="uri">The URI of a file hosted locally.</param>
/// <returns>The URI of a file when it is hosted in CDN.</returns>
string ApplyCdnUri(string uri);
}
}

0 comments on commit 3331d8d

Please sign in to comment.