Skip to content
This repository was archived by the owner on Jan 4, 2022. It is now read-only.
Open
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
17 changes: 16 additions & 1 deletion src/Our.Umbraco.AzureCDNToolkit/AzureCdnToolkit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ public static AzureCdnToolkit Instance
/// </summary>
public string MediaContainer { get; set; }

/// <summary>
/// The timeout in milliseconds used when connecting to the cdn
/// The default value for the <see cref="System.Net.HttpWebRequest"/> is 100 seconds
/// so this is specified as the default value here
/// </summary>
public int CdnConnectionTimeout { get; set; } = 100 * 1000;

/// <summary>
/// Sets all properties
/// </summary>
Expand All @@ -68,7 +75,6 @@ public static AzureCdnToolkit Instance

public void Refresh()
{

if ((WebConfigurationManager.AppSettings["AzureCDNToolkit:UseAzureCdnToolkit"] != null))
{
var useAzureCdnToolkit = bool.Parse(WebConfigurationManager.AppSettings["AzureCDNToolkit:UseAzureCdnToolkit"]);
Expand All @@ -84,6 +90,15 @@ public void Refresh()
this.CdnUrl = WebConfigurationManager.AppSettings["AzureCDNToolkit:CdnUrl"];
this.AssetsContainer = WebConfigurationManager.AppSettings["AzureCDNToolkit:AssetsContainer"] ?? "assets";
this.MediaContainer = WebConfigurationManager.AppSettings["AzureCDNToolkit:MediaContainer"] ?? "media";

if (!string.IsNullOrWhiteSpace(WebConfigurationManager.AppSettings["AzureCDNToolkit:CdnConnectionTimeout"]))
{
int cdnConnectionTimeout = 0;
if (int.TryParse(WebConfigurationManager.AppSettings["AzureCDNToolkit:CdnConnectionTimeout"], out cdnConnectionTimeout))
{
CdnConnectionTimeout = cdnConnectionTimeout;
}
}
}

}
Expand Down
7 changes: 6 additions & 1 deletion src/Our.Umbraco.AzureCDNToolkit/Events/UmbracoEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplica
private void ImageProcessingModule_ValidatingRequest(object sender, ImageProcessor.Web.Helpers.ValidatingRequestEventArgs args)
{
var securityToken = WebConfigurationManager.AppSettings["AzureCDNToolkit:SecurityToken"];
var securityModeEnabled = bool.Parse(WebConfigurationManager.AppSettings["AzureCDNToolkit:SecurityModeEnabled"]);
var securityModeEnabled = false;

if (!bool.TryParse(WebConfigurationManager.AppSettings["AzureCDNToolkit:SecurityModeEnabled"], out securityModeEnabled))
{
securityModeEnabled = false;
}

if (securityModeEnabled && !string.IsNullOrWhiteSpace(args.QueryString) && !string.IsNullOrEmpty(securityToken))
{
Expand Down
70 changes: 53 additions & 17 deletions src/Our.Umbraco.AzureCDNToolkit/UrlHelperRenderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static IHtmlString GetCropCdnUrl(this UrlHelper urlHelper,

public static IHtmlString ResolveCdn(this UrlHelper urlHelper, string path, bool asset = true, bool htmlEncode = true)
{
return ResolveCdn(urlHelper, path, AzureCdnToolkit.Instance.CdnPackageVersion, asset, htmlEncode:htmlEncode);
return ResolveCdn(urlHelper, path, AzureCdnToolkit.Instance.CdnPackageVersion, asset, htmlEncode: htmlEncode);
}

// Special version of the method with fallback image for TinyMce converter
Expand Down Expand Up @@ -166,7 +166,7 @@ public static IHtmlString ResolveCdn(this UrlHelper urlHelper, string path, stri

if (asset && !path.InvariantContains("/media/"))
{
cdnPath = string.Format("{0}/{1}", AzureCdnToolkit.Instance.CdnUrl, AzureCdnToolkit.Instance.AssetsContainer);
cdnPath = string.Format("{0}/{1}", AzureCdnToolkit.Instance.CdnUrl, AzureCdnToolkit.Instance.AssetsContainer);
}
else
{
Expand Down Expand Up @@ -228,9 +228,12 @@ internal static IHtmlString UrlToCdnUrl(string cropUrl, bool htmlEncode, string
// If toolkit disabled return orginal string
if (!AzureCdnToolkit.Instance.UseAzureCdnToolkit)
{
LogHelper.Info(typeof(UrlHelperRenderExtensions), "AzureCdnToolkit is disabled");
return new HtmlString(cropUrl);
}

LogHelper.Info(typeof(UrlHelperRenderExtensions), "AzureCdnToolkit is enabled");

if (string.IsNullOrEmpty(currentDomain))
{
currentDomain = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
Expand Down Expand Up @@ -260,28 +263,61 @@ internal static IHtmlString UrlToCdnUrl(string cropUrl, bool htmlEncode, string
absoluteCropPath = string.Format("{0}&securitytoken={1}", absoluteCropPath, securityToken);
}

// Retry five times before giving up to account for networking issues
TryFiveTimes(() =>
// lazy load the image
Lazy<string> LazyLoadCdnImage = new Lazy<string>(() =>
{
var request = (HttpWebRequest)WebRequest.Create(absoluteCropPath);
request.Method = "HEAD";
using (var response = (HttpWebResponse)request.GetResponse())
string result = null;

try
{
var responseCode = response.StatusCode;
if (responseCode.Equals(HttpStatusCode.OK))

// parse the image through the handler directly

// HttpContext.Current



// Retry five times before giving up to account for networking issues
TryFiveTimes(() =>
{
var absoluteUri = response.ResponseUri.AbsoluteUri;
newCachedImage.CacheUrl = absoluteUri;
var request = (HttpWebRequest)WebRequest.Create(absoluteCropPath);
request.Timeout = AzureCdnToolkit.Instance.CdnConnectionTimeout;
request.Method = "HEAD";
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseCode = response.StatusCode;
if (responseCode.Equals(HttpStatusCode.OK))
{
result = response.ResponseUri.AbsoluteUri;
}
}
});
}
catch(Exception ex)
{
LogHelper.Error(typeof(UrlHelperRenderExtensions), "Error resolving media url from the CDN", ex);

// this is to mark URLs returned direct to Blob by ImageProcessor as not fully resolved
newCachedImage.Resolved = absoluteUri.InvariantContains(AzureCdnToolkit.Instance.CdnUrl);
// we have tried 5 times and failed so let's cache the normal address
newCachedImage = new CachedImage { WebUrl = cropUrl };
newCachedImage.Resolved = false;
newCachedImage.CacheUrl = cropUrl;
Cache.InsertCacheItem<CachedImage>(cacheKey, () => newCachedImage);

Cache.InsertCacheItem<CachedImage>(cacheKey, () => newCachedImage);
fullUrlPath = response.ResponseUri.AbsoluteUri;
}
result = cropUrl;
}
});

newCachedImage.CacheUrl = result;
// this is to mark URLs returned direct to Blob by ImageProcessor as not fully resolved
newCachedImage.Resolved = fullUrlPath.InvariantContains(AzureCdnToolkit.Instance.CdnUrl);
Cache.InsertCacheItem<CachedImage>(cacheKey, () => newCachedImage);

return result;

},
System.Threading.LazyThreadSafetyMode.PublicationOnly);


fullUrlPath = LazyLoadCdnImage.Value;
}
else
{
Expand Down