Beispiel #1
0
        private string GetCachePath()
        {
            string cachedPath = string.Empty;

            if (AbsoluteCachePath != null)
            {
                // Use an sha1 hash of the full path including the querystring to create the image name.
                // That name can also be used as a key for the cached image and we should be able to use
                // The characters of that hash as subfolders.
                string parsedExtension   = ImageHelpers.GetExtension(this.fullPath);
                string fallbackExtension = this.imageName.Substring(this.imageName.LastIndexOf(".", StringComparison.Ordinal) + 1);
                string encryptedName     = this.fullPath.ToSHA1Fingerprint();

                // Collision rate of about 1 in 10000 for the folder structure.
                string pathFromKey = string.Join("\\", encryptedName.ToCharArray().Take(6));

                string cachedFileName = string.Format(
                    "{0}.{1}",
                    encryptedName,
                    !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : fallbackExtension);

                cachedPath = Path.Combine(AbsoluteCachePath, pathFromKey, cachedFileName);
            }

            return(cachedPath);
        }
        /// <summary>
        /// Gets a string identifying the cached file name.
        /// </summary>
        /// <returns>
        /// The asynchronous <see cref="Task"/> returning the value.
        /// </returns>
        public override async Task <string> CreateCachedFileNameAsync()
        {
            string streamHash = string.Empty;

            try
            {
                if (new Uri(this.RequestPath).IsFile)
                {
                    // Get the hash for the filestream. That way we can ensure that if the image is
                    // updated but has the same name we will know.
                    FileInfo imageFileInfo = new FileInfo(this.RequestPath);
                    if (imageFileInfo.Exists)
                    {
                        // Pull the latest info.
                        imageFileInfo.Refresh();

                        // Checking the stream itself is far too processor intensive so we make a best guess.
                        string creation = imageFileInfo.CreationTimeUtc.ToString(CultureInfo.InvariantCulture);
                        string length   = imageFileInfo.Length.ToString(CultureInfo.InvariantCulture);
                        streamHash = string.Format("{0}{1}", creation, length);
                    }
                }
                else
                {
                    // Try and get the headers for the file, this should allow cache busting for remote files.
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.RequestPath);
                    request.Method = "HEAD";

                    using (HttpWebResponse response = (HttpWebResponse)(await request.GetResponseAsync()))
                    {
                        string lastModified = response.LastModified.ToUniversalTime().ToString(CultureInfo.InvariantCulture);
                        string length       = response.ContentLength.ToString(CultureInfo.InvariantCulture);
                        streamHash = string.Format("{0}{1}", lastModified, length);
                    }
                }

                // TODO: Pull from other cloud folder/bucket to match the AzureBlobCache behaviour.
            }
            catch
            {
                streamHash = string.Empty;
            }

            // Use an sha1 hash of the full path including the querystring to create the image name.
            // That name can also be used as a key for the cached image and we should be able to use
            // The characters of that hash as sub-folders.
            string parsedExtension = ImageHelpers.GetExtension(this.FullPath, this.Querystring);
            string encryptedName   = (streamHash + this.FullPath).ToSHA1Fingerprint();

            string cachedFileName = string.Format(
                "{0}.{1}",
                encryptedName,
                !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : "jpg");

            return(cachedFileName);
        }
Beispiel #3
0
        /// <summary>
        /// Gets the full transformed cached paths for the image.
        /// The images are stored in paths that are based upon the SHA1 of their full request path
        /// taking the individual characters of the hash to determine their location.
        /// This allows us to store millions of images.
        /// </summary>
        private void GetCachePaths()
        {
            string streamHash = string.Empty;

            if (AbsoluteCachePath != null)
            {
                try
                {
                    if (new Uri(this.requestPath).IsFile)
                    {
                        // Get the hash for the filestream. That way we can ensure that if the image is
                        // updated but has the same name we will know.
                        FileInfo imageFileInfo = new FileInfo(this.requestPath);
                        if (imageFileInfo.Exists)
                        {
                            // Pull the latest info.
                            imageFileInfo.Refresh();

                            // Checking the stream itself is far too processor intensive so we make a best guess.
                            string creation = imageFileInfo.CreationTimeUtc.ToString(CultureInfo.InvariantCulture);
                            string length   = imageFileInfo.Length.ToString(CultureInfo.InvariantCulture);
                            streamHash = string.Format("{0}{1}", creation, length);
                        }
                    }
                }
                catch
                {
                    streamHash = string.Empty;
                }

                // Use an sha1 hash of the full path including the querystring to create the image name.
                // That name can also be used as a key for the cached image and we should be able to use
                // The characters of that hash as sub-folders.
                string parsedExtension = ImageHelpers.GetExtension(this.fullPath, this.querystring);
                string encryptedName   = (streamHash + this.fullPath).ToSHA1Fingerprint();

                // Collision rate of about 1 in 10000 for the folder structure.
                string pathFromKey        = string.Join("\\", encryptedName.ToCharArray().Take(6));
                string virtualPathFromKey = pathFromKey.Replace(@"\", "/");

                string cachedFileName = string.Format(
                    "{0}.{1}",
                    encryptedName,
                    !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : "jpg");

                this.physicalCachedPath = Path.Combine(AbsoluteCachePath, pathFromKey, cachedFileName);
                this.virtualCachedPath  = Path.Combine(VirtualCachePath, virtualPathFromKey, cachedFileName).Replace(@"\", "/");
            }
        }
        /// <summary>
        /// Gets a string identifying the cached file name.
        /// </summary>
        /// <returns>
        /// The asynchronous <see cref="Task"/> returning the value.
        /// </returns>
        public virtual async Task <string> CreateCachedFileNameAsync()
        {
            string streamHash = string.Empty;

            try
            {
                if (new Uri(this.RequestPath).IsFile)
                {
                    // Get the hash for the filestream. That way we can ensure that if the image is
                    // updated but has the same name we will know.
                    FileInfo imageFileInfo = new FileInfo(this.RequestPath);
                    if (imageFileInfo.Exists)
                    {
                        // Pull the latest info.
                        imageFileInfo.Refresh();

                        // Checking the stream itself is far too processor intensive so we make a best guess.
                        string creation = imageFileInfo.CreationTimeUtc.ToString(CultureInfo.InvariantCulture);
                        string length   = imageFileInfo.Length.ToString(CultureInfo.InvariantCulture);
                        streamHash = string.Format("{0}{1}", creation, length);
                    }
                }
            }
            catch
            {
                streamHash = string.Empty;
            }

            // Use an sha1 hash of the full path including the querystring to create the image name.
            // That name can also be used as a key for the cached image and we should be able to use
            // The characters of that hash as sub-folders.
            string parsedExtension = ImageHelpers.GetExtension(this.FullPath, this.Querystring);
            string encryptedName   = (streamHash + this.FullPath).ToSHA1Fingerprint();

            string cachedFileName = string.Format(
                "{0}.{1}",
                encryptedName,
                !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : "jpg");

            return(await Task.FromResult(cachedFileName));
        }
        /// <summary>
        /// Gets a string identifying the cached file name.
        /// </summary>
        /// <returns>
        /// The asynchronous <see cref="Task"/> returning the value.
        /// </returns>
        public override async Task <string> CreateCachedFileNameAsync()
        {
            string streamHash = string.Empty;

            try
            {
                if (new Uri(this.RequestPath).IsFile)
                {
                    // Get the hash for the filestream. That way we can ensure that if the image is
                    // updated but has the same name we will know.
                    FileInfo imageFileInfo = new FileInfo(this.RequestPath);
                    if (imageFileInfo.Exists)
                    {
                        // Pull the latest info.
                        imageFileInfo.Refresh();

                        // Checking the stream itself is far too processor intensive so we make a best guess.
                        string creation = imageFileInfo.CreationTimeUtc.ToString(CultureInfo.InvariantCulture);
                        string length   = imageFileInfo.Length.ToString(CultureInfo.InvariantCulture);
                        streamHash = string.Format("{0}{1}", creation, length);
                    }
                }
                else if (this.cloudSourceBlobContainer != null)
                {
                    string container = RemoteRegex.Replace(this.cloudSourceBlobContainer.Uri.ToString(), string.Empty);
                    string blobPath  = RemoteRegex.Replace(this.RequestPath, string.Empty);
                    blobPath = blobPath.Replace(container, string.Empty).TrimStart('/');
                    CloudBlockBlob blockBlob = this.cloudSourceBlobContainer.GetBlockBlobReference(blobPath);

                    if (await blockBlob.ExistsAsync())
                    {
                        // Pull the latest info.
                        await blockBlob.FetchAttributesAsync();

                        if (blockBlob.Properties.LastModified.HasValue)
                        {
                            string creation = blockBlob.Properties
                                              .LastModified.Value.UtcDateTime
                                              .ToString(CultureInfo.InvariantCulture);

                            string length = blockBlob.Properties.Length.ToString(CultureInfo.InvariantCulture);
                            streamHash = string.Format("{0}{1}", creation, length);
                        }
                    }
                }
                else
                {
                    // Try and get the headers for the file, this should allow cache busting for remote files.
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.RequestPath);
                    request.Method = "HEAD";

                    using (HttpWebResponse response = (HttpWebResponse)(await request.GetResponseAsync()))
                    {
                        string lastModified = response.LastModified.ToUniversalTime().ToString(CultureInfo.InvariantCulture);
                        string length       = response.ContentLength.ToString(CultureInfo.InvariantCulture);
                        streamHash = string.Format("{0}{1}", lastModified, length);
                    }
                }
            }
            catch
            {
                streamHash = string.Empty;
            }

            // Use an sha1 hash of the full path including the querystring to create the image name.
            // That name can also be used as a key for the cached image and we should be able to use
            // The characters of that hash as sub-folders.
            string parsedExtension = ImageHelpers.GetExtension(this.FullPath, this.Querystring);
            string encryptedName   = (streamHash + this.FullPath).ToSHA1Fingerprint();

            string cachedFileName = string.Format(
                "{0}.{1}",
                encryptedName,
                !string.IsNullOrWhiteSpace(parsedExtension) ? parsedExtension.Replace(".", string.Empty) : "jpg");

            return(cachedFileName);
        }