コード例 #1
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (this.streamCachedImage)
            {
                // Write the blob storage directly to the stream
                request.Method = "GET";

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    Stream cachedStream = response.GetResponseStream();

                    if (cachedStream != null)
                    {
                        HttpResponse contextResponse = context.Response;
                        cachedStream.CopyTo(contextResponse.OutputStream);
                        ImageProcessingModule.SetHeaders(context, this.mimeType, null, this.MaxDays, response.StatusCode);
                    }
                }
            }
            else
            {
                // Redirect the request to the blob URL
                request.Method = "HEAD";

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    HttpStatusCode responseCode = response.StatusCode;
                    ImageProcessingModule.AddCorsRequestHeaders(context);
                    context.Response.Redirect(responseCode == HttpStatusCode.NotFound ? this.CachedPath : this.cachedRewritePath, false);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (this.streamCachedImage)
            {
                // Write the blob storage directly to the stream
                request.Method = "GET";

                TryFiveTimes(
                    () =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        Stream cachedStream = response.GetResponseStream();

                        if (cachedStream != null)
                        {
                            HttpResponse contextResponse = context.Response;
                            cachedStream.CopyTo(contextResponse.OutputStream);
                            ImageProcessingModule.SetHeaders(context, response.ContentType, null, this.BrowserMaxDays, response.StatusCode);
                        }
                    }
                },
                    () =>
                {
                    ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to stream cached path: " + this.cachedRewritePath);
                });
            }
            else
            {
                // Redirect the request to the blob URL
                request.Method = "HEAD";

                TryFiveTimes(
                    () =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        HttpStatusCode responseCode = response.StatusCode;
                        ImageProcessingModule.AddCorsRequestHeaders(context);
                        context.Response.Redirect(responseCode == HttpStatusCode.NotFound ? this.CachedPath : this.cachedRewritePath, false);
                    }
                },
                    () =>
                {
                    ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to rewrite cached path to: " + this.cachedRewritePath);
                });
            }
        }
コード例 #3
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (this.streamCachedImage)
            {
                // Write the blob storage directly to the stream
                request.Method = "GET";

                TryFiveTimes(() =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        Stream cachedStream = response.GetResponseStream();

                        if (cachedStream != null)
                        {
                            HttpResponse contextResponse = context.Response;
                            cachedStream.CopyTo(contextResponse.OutputStream);

                            // Mimetype can be null when returning from the cache.
                            ImageProcessingModule.SetHeaders(
                                context,
                                string.IsNullOrWhiteSpace(this.mimeType) ? contextResponse.ContentType : this.mimeType,
                                null,
                                this.MaxDays,
                                response.StatusCode);
                        }
                    }
                });
            }
            else
            {
                // Redirect the request to the blob URL
                request.Method = "HEAD";

                TryFiveTimes(() =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        HttpStatusCode responseCode = response.StatusCode;
                        ImageProcessingModule.AddCorsRequestHeaders(context);
                        context.Response.Redirect(responseCode == HttpStatusCode.NotFound ? this.CachedPath : this.cachedRewritePath, false);
                    }
                });
            }
        }
コード例 #4
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (this.streamCachedImage)
            {
                // Map headers to enable 304s to pass through
                if (context.Request.Headers["If-Modified-Since"] != null)
                {
                    request.IfModifiedSince = DateTime.Parse(context.Request.Headers["If-Modified-Since"]);
                }

                string[] mapRequestHeaders = { "Cache-Control", "If-None-Match" };
                foreach (string h in mapRequestHeaders)
                {
                    if (context.Request.Headers[h] != null)
                    {
                        request.Headers.Add(h, context.Request.Headers[h]);
                    }
                }

                // Write the blob storage directly to the stream
                request.Method = "GET";

                TryFiveTimes(
                    () =>
                {
                    HttpWebResponse response;
                    try
                    {
                        response = (HttpWebResponse)request.GetResponse();
                    }
                    catch (WebException ex)
                    {
                        // A 304 is not an error
                        if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
                        {
                            response = (HttpWebResponse)ex.Response;
                        }
                        else
                        {
                            throw;
                        }
                    }

                    Stream cachedStream = response.GetResponseStream();

                    if (cachedStream != null)
                    {
                        HttpResponse contextResponse = context.Response;
                        contextResponse.Headers.Add("ETag", response.Headers["ETag"]);
                        contextResponse.Headers.Add("Last-Modified", response.Headers["Last-Modified"]);
                        cachedStream.CopyTo(contextResponse.OutputStream);     // Will be empty on 304s
                        ImageProcessingModule.SetHeaders(context, response.StatusCode == HttpStatusCode.NotModified ? null : response.ContentType, null, this.BrowserMaxDays, response.StatusCode);
                    }

                    response.Dispose();
                },
                    () =>
                {
                    ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to stream cached path: " + this.cachedRewritePath);
                });
            }
            else
            {
                // Redirect the request to the blob URL
                request.Method  = "HEAD";
                request.Timeout = this.timeout;
                TryFiveTimes(
                    () =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        HttpStatusCode responseCode = response.StatusCode;
                        ImageProcessingModule.AddCorsRequestHeaders(context);
                        context.Response.Redirect(responseCode == HttpStatusCode.NotFound ? this.CachedPath : this.cachedRewritePath, false);
                    }
                },
                    () =>
                {
                    ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to rewrite cached path to: " + this.cachedRewritePath);
                });
            }
        }
コード例 #5
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            if (streamCachedImage)
            {
                string         blobPath  = this.CachedPath.Substring(cloudCachedBlobContainer.Uri.ToString().Length + 1);
                CloudBlockBlob blockBlob = cloudCachedBlobContainer.GetBlockBlobReference(blobPath);

                if (blockBlob.Exists())
                {
                    using (MemoryStream cachedStream = MemoryStreamPool.Shared.GetStream())
                    {
                        // Map headers to enable 304s to pass through
                        TrySetIfModifiedSinceDate(context, out AccessCondition accessCondition);
                        const string IfNoneMatch = "If-None-Match";

                        // TODO: Cache-Control?
                        if (context.Request.Headers[IfNoneMatch] != null)
                        {
                            accessCondition.IfNoneMatchETag = context.Request.Headers[IfNoneMatch];
                        }

                        bool is304 = false;
                        try
                        {
                            blockBlob.DownloadToStream(cachedStream, accessCondition);
                            cachedStream.Position = 0;
                        }
                        catch (StorageException ex)
                        {
                            // A 304 is not a true error, we still need to feed back.
                            var webException = ex.InnerException as WebException;
                            if (!(webException is null))
                            {
                                if (webException.Response != null && (((HttpWebResponse)webException.Response).StatusCode == HttpStatusCode.NotModified))
                                {
                                    is304 = true;
                                }
                                else
                                {
                                    ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to stream cached path: " + this.cachedRewritePath);
                                    return;
                                }
                            }
                        }

                        BlobProperties properties      = blockBlob.Properties;
                        HttpResponse   contextResponse = context.Response;

                        if (!string.IsNullOrWhiteSpace(properties.ETag))
                        {
                            contextResponse.Headers.Add("ETag", properties.ETag);
                        }

                        if (properties.LastModified.HasValue)
                        {
                            contextResponse.Headers.Add("Last-Modified", properties.LastModified.Value.UtcDateTime.ToString("R"));
                        }

                        cachedStream.CopyTo(contextResponse.OutputStream); // Will be empty on 304s

                        if (contextResponse.OutputStream.CanSeek)
                        {
                            contextResponse.OutputStream.Position = 0;
                        }

                        ImageProcessingModule.SetHeaders(
                            context,
                            !is304 ? properties.ContentType : null,
                            null,
                            this.BrowserMaxDays,
                            !is304 ? HttpStatusCode.OK : HttpStatusCode.NotModified);
                    }
                }
            }
            else
            {
                // Prevent redundant metadata request if paths match.
                if (this.CachedPath == this.cachedRewritePath)
                {
                    ImageProcessingModule.AddCorsRequestHeaders(context);
                    context.Response.Redirect(this.CachedPath, false);
                    return;
                }

                var request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

                // Redirect the request to the blob URL
                request.Method  = "HEAD";
                request.Timeout = timeout;

                HttpWebResponse response;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                    response.Dispose();
                    ImageProcessingModule.AddCorsRequestHeaders(context);
                    context.Response.Redirect(this.cachedRewritePath, false);
                }
                catch (WebException ex)
                {
                    response = (HttpWebResponse)ex.Response;

                    if (response != null)
                    {
                        HttpStatusCode responseCode = response.StatusCode;

                        // A 304 is not an error
                        // It appears that some CDN's on Azure (Akamai) do not work properly when making head requests.
                        // They will return a response url and other headers but a 500 status code.
                        if (responseCode == HttpStatusCode.NotModified ||
                            response.ResponseUri.AbsoluteUri.Equals(this.cachedRewritePath, StringComparison.OrdinalIgnoreCase))
                        {
                            response.Dispose();
                            ImageProcessingModule.AddCorsRequestHeaders(context);
                            context.Response.Redirect(this.cachedRewritePath, false);
                        }
                        else
                        {
                            response.Dispose();
                            ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to rewrite cached path to: " + this.cachedRewritePath);
                        }
                    }
                    else
                    {
                        // It's a 404, we should redirect to the cached path we have just saved to.
                        ImageProcessingModule.AddCorsRequestHeaders(context);
                        context.Response.Redirect(this.CachedPath, false);
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (this.streamCachedImage)
            {
                // Map headers to enable 304s to pass through
                if (context.Request.Headers["If-Modified-Since"] != null)
                {
                    TrySetIfModifiedSinceDate(context, request);
                }

                string[] mapRequestHeaders = { "Cache-Control", "If-None-Match" };
                foreach (string h in mapRequestHeaders)
                {
                    if (context.Request.Headers[h] != null)
                    {
                        request.Headers.Add(h, context.Request.Headers[h]);
                    }
                }

                // Write the blob storage directly to the stream
                request.Method  = "GET";
                request.Timeout = this.timeout;

                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException ex)
                {
                    // A 304 is not an error
                    if (ex.Response != null && ((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified)
                    {
                        response = (HttpWebResponse)ex.Response;
                    }
                    else
                    {
                        response?.Dispose();
                        ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to stream cached path: " + this.cachedRewritePath);
                        return;
                    }
                }

                Stream cachedStream = response.GetResponseStream();

                if (cachedStream != null)
                {
                    HttpResponse contextResponse = context.Response;

                    // If streaming but not using a CDN the headers will be null.
                    // See https://github.com/JimBobSquarePants/ImageProcessor/pull/466
                    string etagHeader = response.Headers["ETag"];
                    if (!string.IsNullOrWhiteSpace(etagHeader))
                    {
                        contextResponse.Headers.Add("ETag", etagHeader);
                    }

                    string lastModifiedHeader = response.Headers["Last-Modified"];
                    if (!string.IsNullOrWhiteSpace(lastModifiedHeader))
                    {
                        contextResponse.Headers.Add("Last-Modified", lastModifiedHeader);
                    }

                    cachedStream.CopyTo(contextResponse.OutputStream); // Will be empty on 304s
                    ImageProcessingModule.SetHeaders(
                        context,
                        response.StatusCode == HttpStatusCode.NotModified ? null : response.ContentType,
                        null,
                        this.BrowserMaxDays,
                        response.StatusCode);
                }

                cachedStream?.Dispose();
                response.Dispose();
            }
            else
            {
                // Redirect the request to the blob URL
                request.Method  = "HEAD";
                request.Timeout = this.timeout;

                HttpWebResponse response;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                    response.Dispose();
                    ImageProcessingModule.AddCorsRequestHeaders(context);
                    context.Response.Redirect(this.cachedRewritePath, false);
                }
                catch (WebException ex)
                {
                    response = (HttpWebResponse)ex.Response;

                    if (response != null)
                    {
                        HttpStatusCode responseCode = response.StatusCode;

                        // A 304 is not an error
                        if (responseCode == HttpStatusCode.NotModified)
                        {
                            response.Dispose();
                            ImageProcessingModule.AddCorsRequestHeaders(context);
                            context.Response.Redirect(this.cachedRewritePath, false);
                        }
                        else
                        {
                            response.Dispose();
                            ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>("Unable to rewrite cached path to: " + this.cachedRewritePath);
                        }
                    }
                    else
                    {
                        // It's a 404, we should redirect to the cached path we have just saved to.
                        ImageProcessingModule.AddCorsRequestHeaders(context);
                        context.Response.Redirect(this.CachedPath, false);
                    }
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            var request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);

            if (streamCachedImage)
            {
                // Map headers to enable 304s to pass through
                if (context.Request.Headers["If-Modified-Since"] != null)
                {
                    TrySetIfModifiedSinceDate(context, request);
                }

                string[] mapRequestHeaders = { "Cache-Control", "If-None-Match" };
                foreach (string h in mapRequestHeaders)
                {
                    if (context.Request.Headers[h] != null)
                    {
                        request.Headers.Add(h, context.Request.Headers[h]);
                    }
                }

                // Write the blob storage directly to the stream
                request.Method  = "GET";
                request.Timeout = timeout;

                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException ex)
                {
                    // A 304 is not an error
                    // It appears that some CDN's on Azure (Akamai) do not work properly when making head requests.
                    // They will return a response url and other headers but a 500 status code.
                    if (ex.Response != null && (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified ||
                                                ex.Response.ResponseUri.AbsoluteUri.Equals(this.cachedRewritePath, StringComparison.OrdinalIgnoreCase)))
                    {
                        response = (HttpWebResponse)ex.Response;
                    }
                    else
                    {
                        response?.Dispose();
                        ImageProcessorBootstrapper.Instance.Logger.Log <AmazonS3Cache>("Unable to stream cached path: " + this.cachedRewritePath);
                        return;
                    }
                }

                Stream cachedStream = response.GetResponseStream();

                if (cachedStream != null)
                {
                    HttpResponse contextResponse = context.Response;

                    // If streaming but not using a CDN the headers will be null.
                    // See https://github.com/JimBobSquarePants/ImageProcessor/pull/466
                    string etagHeader = response.Headers["ETag"];
                    if (!string.IsNullOrWhiteSpace(etagHeader))
                    {
                        contextResponse.Headers.Add("ETag", etagHeader);
                    }

                    string lastModifiedHeader = response.Headers["Last-Modified"];
                    if (!string.IsNullOrWhiteSpace(lastModifiedHeader))
                    {
                        contextResponse.Headers.Add("Last-Modified", lastModifiedHeader);
                    }

                    cachedStream.CopyTo(contextResponse.OutputStream); // Will be empty on 304s
                    ImageProcessingModule.SetHeaders(
                        context,
                        response.StatusCode == HttpStatusCode.NotModified ? null : response.ContentType,
                        null,
                        this.BrowserMaxDays,
                        response.StatusCode);
                }

                cachedStream?.Dispose();
                response.Dispose();
            }
            else
            {
                // Prevent redundant metadata request if paths match.
                if (this.CachedPath == this.cachedRewritePath)
                {
                    ImageProcessingModule.SetHeaders(context, null, null, this.BrowserMaxDays);
                    context.Response.Redirect(this.CachedPath, false);
                    return;
                }

                // Redirect the request to the blob URL
                request.Method  = "HEAD";
                request.Timeout = timeout;

                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                    response.Dispose();

                    ImageProcessingModule.SetHeaders(context, null, null, this.BrowserMaxDays);
                    context.Response.Redirect(this.cachedRewritePath, false);
                }
                catch (WebException ex)
                {
                    response = (HttpWebResponse)ex.Response;

                    if (response != null)
                    {
                        HttpStatusCode responseCode = response.StatusCode;

                        // A 304 is not an error
                        // It appears that some CDN's on Azure (Akamai) do not work properly when making head requests.
                        // They will return a response url and other headers but a 500 status code.
                        if (responseCode == HttpStatusCode.NotModified ||
                            response.ResponseUri.AbsoluteUri.Equals(this.cachedRewritePath, StringComparison.OrdinalIgnoreCase))
                        {
                            response.Dispose();

                            ImageProcessingModule.SetHeaders(context, null, null, this.BrowserMaxDays);
                            context.Response.Redirect(this.cachedRewritePath, false);
                        }
                        else
                        {
                            response.Dispose();
                            ImageProcessorBootstrapper.Instance.Logger.Log <AmazonS3Cache>("Unable to rewrite cached path to: " + this.cachedRewritePath);
                        }
                    }
                    else
                    {
                        // It's a 404, we should redirect to the cached path we have just saved to.
                        ImageProcessingModule.SetHeaders(context, null, null, this.BrowserMaxDays);
                        context.Response.Redirect(this.CachedPath, false);
                    }
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Rewrites the path to point to the cached image.
        /// </summary>
        /// <param name="context">
        /// The <see cref="HttpContext"/> encapsulating all information about the request.
        /// </param>
        public override void RewritePath(HttpContext context)
        {
            if (streamCachedImage)
            {
                string         blobPath  = this.CachedPath.Substring(cloudCachedBlobContainer.Uri.ToString().Length + 1);
                CloudBlockBlob blockBlob = cloudCachedBlobContainer.GetBlockBlobReference(blobPath);

                if (blockBlob.Exists())
                {
                    using (MemoryStream cachedStream = MemoryStreamPool.Shared.GetStream())
                    {
                        // Map headers to enable 304s to pass through
                        TrySetIfModifiedSinceDate(context, out AccessCondition accessCondition);
                        const string IfNoneMatch = "If-None-Match";

                        // TODO: Cache-Control?
                        if (context.Request.Headers[IfNoneMatch] != null)
                        {
                            accessCondition.IfNoneMatchETag = context.Request.Headers[IfNoneMatch];
                        }

                        bool is304 = false;
                        try
                        {
                            blockBlob.DownloadToStream(cachedStream, accessCondition);
                            cachedStream.Position = 0;
                        }
                        catch (StorageException ex)
                        {
                            // A 304 is not a true error, we still need to feed back.
                            if (ex.RequestInformation?.HttpStatusCode == (int)HttpStatusCode.NotModified)
                            {
                                is304 = true;
                            }
                            else if (ex.InnerException is WebException webException &&
                                     webException.Response is HttpWebResponse httpWebResponse &&
                                     httpWebResponse.StatusCode == HttpStatusCode.NotModified)
                            {
                                is304 = true;
                            }
                            else
                            {
                                var sb = new StringBuilder();
                                sb.AppendFormat("Unable to stream cached path: {0}", this.cachedRewritePath);
                                sb.AppendLine();
                                sb.AppendFormat("Exception: {0}", ex.ToString());

                                ImageProcessorBootstrapper.Instance.Logger.Log <AzureBlobCache>(sb.ToString());
                                return;
                            }
                        }

                        BlobProperties properties      = blockBlob.Properties;
                        HttpResponse   contextResponse = context.Response;

                        if (!string.IsNullOrWhiteSpace(properties.ETag))
                        {
                            contextResponse.Headers.Add("ETag", properties.ETag);
                        }

                        if (properties.LastModified.HasValue)
                        {
                            contextResponse.Headers.Add("Last-Modified", properties.LastModified.Value.UtcDateTime.ToString("R"));
                        }

                        cachedStream.CopyTo(contextResponse.OutputStream); // Will be empty on 304s

                        if (contextResponse.OutputStream.CanSeek)
                        {
                            contextResponse.OutputStream.Position = 0;
                        }

                        ImageProcessingModule.SetHeaders(
                            context,
                            !is304 ? properties.ContentType : null,
                            null,
                            this.BrowserMaxDays,
                            !is304 ? HttpStatusCode.OK : HttpStatusCode.NotModified);
                    }