protected static StaticWebDownloadResult DownloadResource(string rootUrl, string resourceUrl, AllowedResourceTypeConfigurationElement typeConfiguration)
        {
            StaticWebDownloadResult result = new StaticWebDownloadResult();

            // We have no extension to go on, look at content-type
            WebClient referencableClient = new WebClient();

            referencableClient.Headers.Set(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 StaticWebPlugin/0.1");
            referencableClient.Encoding = Encoding.UTF8;

            try
            {
                byte[] data = referencableClient.DownloadData(rootUrl + resourceUrl);
                result.Data = data;
            }
            catch (WebException)
            {
                return(null);
            }

            var contentTypeResponse = referencableClient.ResponseHeaders[HttpResponseHeader.ContentType];

            if (string.IsNullOrEmpty(contentTypeResponse))
            {
                return(null);
            }

            string contentType = contentTypeResponse.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();

            if (string.IsNullOrEmpty(contentType))
            {
                return(null);
            }

            if (typeConfiguration.MimeType.StartsWith("*"))
            {
                var extensionConfig = GetConfigurationForKnownContentType(contentType);
                if (extensionConfig != null && !IsDownloadPrevented(resourceUrl + extensionConfig.FileExtension))
                {
                    result.TypeConfiguration = extensionConfig;
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                result.TypeConfiguration = typeConfiguration;
            }

            return(result);
        }
        protected static string GetNewResourceUrl(string resourcePath, string resourceUrl, byte[] data, AllowedResourceTypeConfigurationElement typeConfiguration)
        {
            if (typeConfiguration == null)
            {
                return(null);
            }

            if (typeConfiguration.UseResourceFolder)
            {
                resourcePath = "/" + resourcePath.Replace(@"\", "/") + "/";
            }
            else
            {
                resourcePath = "/";
            }

            if (typeConfiguration.UseResourceUrl)
            {
                if (string.IsNullOrEmpty(resourceUrl))
                {
                    resourceUrl = "";
                }

                /* Ugly hack: remove as soon as possible
                 * make sure to not get a folder name with a file name, for example: /globalassets/alloy-plan/alloyplan.png/size700.png
                 * alloyplan.png here would cause error (IF we also have the orginal image) as we can't have a file and a folder with the same name.
                 */
                resourceUrl = resourceUrl.Replace(typeConfiguration.FileExtension, "");

                resourceUrl = EnsureUrlWithoutParams(resourceUrl);
            }

            // If we have disabled usage of resourceUrl, force usage of hash
            string hash = "";

            if (!typeConfiguration.UseResourceUrl || typeConfiguration.UseHash)
            {
                // We can't calculate hash on null, abort
                if (data == null)
                {
                    return(null);
                }

                using (var sha256 = new System.Security.Cryptography.SHA256Managed())
                {
                    var hashData = sha256.ComputeHash(data);
                    hash = Convert.ToBase64String(hashData, Base64FormattingOptions.None).Replace("/", "-").Replace("=", "_").Replace("+", ".");
                }
            }

            if (typeConfiguration.UseResourceUrl && typeConfiguration.UseHash)
            {
                return((resourcePath + EnsureFileSystemValid(resourceUrl + "-" + hash + typeConfiguration.FileExtension)).Replace("//", "/"));
            }
            else if (typeConfiguration.UseHash)
            {
                return((resourcePath + EnsureFileSystemValid(hash + typeConfiguration.FileExtension)).Replace("//", "/"));
            }
            else
            {
                if (resourceUrl.EndsWith("/"))
                {
                    return((resourcePath + EnsureFileSystemValid(resourceUrl)).Replace("//", "/"));
                }
                else
                {
                    return((resourcePath + EnsureFileSystemValid(resourceUrl + typeConfiguration.FileExtension)).Replace("//", "/"));
                }
            }
        }
        protected string EnsureDependencies(string referencingUrl, string content, SiteConfigurationElement siteConfiguration, bool?useTemporaryAttribute, bool ignoreHtmlDependencies, AllowedResourceTypeConfigurationElement typeConfiguration, Dictionary <string, string> currentPageResourcePairs = null, ConcurrentDictionary <string, string> replaceResourcePairs = null, int callDepth = 0)
        {
            string workingContent = content;

            if (typeConfiguration.DenendencyLookup.HasFlag(ResourceDependencyLookup.Html))
            {
                if (!ignoreHtmlDependencies || callDepth == 0)
                {
                    workingContent = _htmlDependencyService.EnsureDependencies(referencingUrl, workingContent, this, siteConfiguration, useTemporaryAttribute, ignoreHtmlDependencies, currentPageResourcePairs, replaceResourcePairs, ++callDepth);
                }
            }
            if (typeConfiguration.DenendencyLookup.HasFlag(ResourceDependencyLookup.Svg))
            {
                workingContent = _svgDependencyService.EnsureDependencies(referencingUrl, workingContent, this, siteConfiguration, useTemporaryAttribute, ignoreHtmlDependencies, currentPageResourcePairs, replaceResourcePairs, ++callDepth);
            }
            if (typeConfiguration.DenendencyLookup.HasFlag(ResourceDependencyLookup.Css))
            {
                workingContent = _cssDependencyService.EnsureDependencies(referencingUrl, workingContent, this, siteConfiguration, useTemporaryAttribute, ignoreHtmlDependencies, currentPageResourcePairs, replaceResourcePairs, ++callDepth);
            }

            return(workingContent);
        }