/// <summary>
        /// Sets the output cache parameters and also the client side caching parameters
        /// </summary>
        /// <param name="context"></param>
        private void SetCaching(HttpContext context, string fileName)
        {
            //This ensures OutputCaching is set for this handler and also controls
            //client side caching on the browser side. Default is 10 days.
            TimeSpan        duration = TimeSpan.FromDays(10);
            HttpCachePolicy cache    = context.Response.Cache;

            cache.SetCacheability(HttpCacheability.Public);
            cache.SetExpires(DateTime.Now.Add(duration));
            cache.SetMaxAge(duration);
            cache.SetValidUntilExpires(true);
            cache.SetLastModified(DateTime.Now);
            cache.SetETag(Guid.NewGuid().ToString());
            //set server OutputCache to vary by our params
            cache.VaryByParams["t"] = true;
            cache.VaryByParams["s"] = true;
            //don't allow varying by wildcard
            cache.SetOmitVaryStar(true);
            //ensure client browser maintains strict caching rules
            cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            //This is the only way to set the max-age cachability header in ASP.Net!
            FieldInfo maxAgeField = cache.GetType().GetField("_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);

            maxAgeField.SetValue(cache, duration);

            //make this output cache dependent on the file if there is one.
            if (!string.IsNullOrEmpty(fileName))
            {
                context.Response.AddFileDependency(fileName);
            }
        }
예제 #2
0
 /// <summary>
 /// Set the response cache headers for WebResource
 /// </summary>
 /// <param name="cache"></param>
 /// <param name="etag"></param>
 /// <param name="maxAge"></param>
 protected static void SetCachingHeadersForWebResource(HttpCachePolicy cache, string etag, TimeSpan maxAge)
 {
     cache.SetCacheability(HttpCacheability.Public);
     cache.VaryByParams["d"] = true;
     cache.SetOmitVaryStar(true);
     cache.SetExpires(DateTime.Now.Add(maxAge));
     cache.SetValidUntilExpires(true);
     cache.VaryByHeaders["Accept-Encoding"] = true;
     cache.SetETag(string.Concat("\"", etag, "\""));
 }
        public void ProcessRequest(HttpContext context)
        {
            string[] jsFiles = context.Request.QueryString["jsfiles"].Split(',');

            List <string> files    = new List <string>();
            StringBuilder response = new StringBuilder();

            foreach (string jsFile in jsFiles)
            {
                if (!jsFile.EndsWith(".js", StringComparison.OrdinalIgnoreCase))
                {
                    //log custom exception
                    context.Response.StatusCode = 403;
                    return;
                }

                try
                {
                    JavaScriptCompressor javaScriptCompressor = new JavaScriptCompressor();
                    string filePath     = context.Server.MapPath(jsFile);
                    string js           = File.ReadAllText(filePath);
                    string compressedJS = javaScriptCompressor.Compress(js);
                    response.Append(compressedJS);
                }
                catch (Exception ex)
                {
                    //log exception
                    context.Response.StatusCode = 500;
                    return;
                }
            }

            context.Response.Write(response.ToString());

            string version = "1.0"; //your dynamic version number here

            context.Response.ContentType = "application/javascript";
            context.Response.AddFileDependencies(files.ToArray());
            HttpCachePolicy cache = context.Response.Cache;

            cache.SetCacheability(HttpCacheability.Public);
            cache.VaryByParams["jsfiles"] = true;
            cache.VaryByParams["version"] = true;
            cache.SetETag(version);
            cache.SetLastModifiedFromFileDependencies();
            cache.SetMaxAge(TimeSpan.FromDays(14));
            cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        }
예제 #4
0
 /// <summary>
 ///     Sets the ETag HTTP header to the specified string.
 /// </summary>
 /// <param name="etag">The text to use for the ETag header. </param>
 /// <exception cref="T:System.ArgumentNullException"><paramref name="etag" /> is null. </exception>
 /// <exception cref="T:System.InvalidOperationException">
 ///     The ETag header has already been set. - or -The
 ///     <see cref="M:System.Web.HttpCachePolicy.SetETagFromFileDependencies" /> has already been called.
 /// </exception>
 public void SetETag(string etag)
 {
     policy.SetETag(etag);
 }
        internal static void ProcessRequestInternal(HttpContext context, string pathOverride)
        {
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;
            string       virtualPathWithPathInfo;
            string       physicalPath;
            FileInfo     fileInfo;
            long         fileLength;
            DateTime     lastModifiedInUtc;
            string       etag;
            string       rangeHeader;

            // custom virtual path providers that don't yeild a MapPathBasedVirtualFile
            // are a special case, and do not support TransmitFile, WriteFile, Range requests,
            // or the cache policy that we apply below

            /*
             * if (ProcessRequestForNonMapPathBasedVirtualFile(request, response, overrideVirtualPath)) {
             *  return;
             * }
             *
             * if (overrideVirtualPath == null)
             * {
             *  virtualPathWithPathInfo = request.Path;
             *  physicalPath = request.PhysicalPath;
             * }
             * else {
             *  virtualPathWithPathInfo = overrideVirtualPath;
             *  physicalPath = request.MapPath(overrideVirtualPath);
             * }
             */

            if (pathOverride != null)
            {
                physicalPath = pathOverride;
            }
            else
            {
                physicalPath = context.Request.PhysicalPath;
            }

            // Debug.Trace("StaticFileHandler", "Path= " + virtualPathWithPathInfo + ", PhysicalPath= " + physicalPath);

            try
            {
                fileInfo = GetFileInfo(physicalPath);
            }
            catch (HttpException hex)
            {
                int    httpCode  = hex.GetHttpCode();
                string httpError = String.Format("{0} ({1})", hex.Message, physicalPath);
                throw new HttpException(httpCode, httpError, hex);
            }

            // Determine Last Modified Time.  We might need it soon
            // if we encounter a Range: and If-Range header
            // Using UTC time to avoid daylight savings time bug 83230
            lastModifiedInUtc = new DateTime(fileInfo.LastWriteTimeUtc.Year,
                                             fileInfo.LastWriteTimeUtc.Month,
                                             fileInfo.LastWriteTimeUtc.Day,
                                             fileInfo.LastWriteTimeUtc.Hour,
                                             fileInfo.LastWriteTimeUtc.Minute,
                                             fileInfo.LastWriteTimeUtc.Second,
                                             0,
                                             DateTimeKind.Utc);

            // Because we can't set a "Last-Modified" header to any time
            // in the future, check the last modified time and set it to
            // DateTime.Now if it's in the future.
            // This is to fix VSWhidbey #402323
            DateTime utcNow = DateTime.UtcNow;

            if (lastModifiedInUtc > utcNow)
            {
                // use 1 second resolution
                lastModifiedInUtc = new DateTime(utcNow.Ticks - (utcNow.Ticks % TimeSpan.TicksPerSecond), DateTimeKind.Utc);
            }

            etag       = GenerateETag(lastModifiedInUtc, utcNow);
            fileLength = fileInfo.Length;

            // is this a Range request?
            rangeHeader = request.Headers["Range"];
            if (rangeHeader != null && rangeHeader.StartsWith("bytes", StringComparison.OrdinalIgnoreCase) &&
                ProcessRangeRequest(context, physicalPath, fileLength, rangeHeader, etag, lastModifiedInUtc))
            {
                return;
            }

            // if we get this far, we're sending the entire file
            SendFile(physicalPath, 0, fileLength, fileLength, context);

            // Specify content type. Use extension to do the mapping
            response.ContentType = MimeMapping.GetMapping(physicalPath);
            // Static file handler supports byte ranges
            response.AppendHeader("Accept-Ranges", "bytes");
            // We want to flush cache entry when static file has changed
            response.AddFileDependency(physicalPath);

            /*
             * NOTE: This was the code originally in the handler:
             * // Set an expires in the future.
             * response.Cache.SetExpires(utcNow.AddMinutes(5));
             * // always set Last-Modified
             * response.Cache.SetLastModified(lastModifiedInUtc);
             * // always set ETag
             * response.Cache.SetETag(etag);
             * // always set Cache-Control to public
             * response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
             */

            // set cache headers
            HttpCachePolicy cachePolicy = response.Cache;

            SetCachingPolicy(cachePolicy);

            // set cache file info
            cachePolicy.SetETag(etag);
            cachePolicy.SetLastModified(lastModifiedInUtc);
        }
예제 #6
0
 public override void SetETag(string etag)
 {
     _httpCachePolicy.SetETag(etag);
 }
예제 #7
0
        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            Image        image;
            ImageFormat  imageFormat;
            string       contentType = null;
            MemoryStream memStream   = null;
            ImageCache   imageCache;
            bool         enableCaching = true;
            bool         cacheValid    = false;
            int          minutes       = Null.NullInteger;
            string       cacheKey      = null;
            string       eTag          = null;
            // Get params
            string imagePath  = context.Request.QueryString["IP"];
            string thumbWidth = context.Request.QueryString["IW"];
            string background = context.Request.QueryString["BC"];
            string duration   = context.Request.QueryString["CD"];
            // Get Header Etag
            string headerEtag = context.Request.Headers["If-None-Match"];
            // When image param start by http or https,
            // it's probably an external image!
            ImageTypeName imageType;

            if (imagePath.IndexOf("http://") > -1 || imagePath.IndexOf("https://") > -1)
            {
                // Image will be get from an http request
                imageType = ImageTypeName.URI;
            }
            else
            {
                // Image will be read from disk
                imageType = ImageTypeName.FilePath;
                imagePath = context.Server.MapPath(imagePath);
            }
            // Default image if not found
            string defaultImage = context.Server.MapPath("~/images/thumbnail.jpg");

            try
            {
                if (string.IsNullOrEmpty(imagePath) == false)
                {
                    // Initializations
                    if (string.IsNullOrEmpty(thumbWidth))
                    {
                        thumbWidth = "175";
                    }
                    if (string.IsNullOrEmpty(duration))
                    {
                        enableCaching = false;
                    }
                    else
                    {
                        minutes = Convert.ToInt32(duration);
                    }
                    // Get cached image thumbnail
                    if (enableCaching)
                    {
                        cacheKey   = string.Format("Store_{0}_{1}_{2}", imagePath, thumbWidth, background);
                        eTag       = cacheKey.GetHashCode().ToString("X");
                        imageCache = (ImageCache)DataCache.GetCache(cacheKey);
                        if (imageCache != null)
                        {
                            contentType = imageCache.ContentType;
                            memStream   = new MemoryStream(imageCache.Data);
                            cacheValid  = true;
                        }
                    }
                    // If cache is null, create the thumbnail
                    if (!cacheValid)
                    {
                        image       = GetImage(imageType, imagePath, defaultImage);
                        imageFormat = image.RawFormat;
                        contentType = GetContentType(imageFormat);
                        Size     thumbSize = ThumbSize(image.Width, image.Height, Convert.ToInt16(thumbWidth));
                        Bitmap   thumb     = new Bitmap(thumbSize.Width, thumbSize.Height);
                        Graphics g         = Graphics.FromImage(thumb);
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                        g.SmoothingMode      = SmoothingMode.HighQuality;
                        g.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                        // Fill background with specified color
                        // to mimics original GIF transparency
                        if (imageFormat.Equals(ImageFormat.Gif))
                        {
                            Brush bgBrush = GetBrush(GetHexDigits(background));
                            g.FillRectangle(bgBrush, 0, 0, thumbSize.Width, thumbSize.Height);
                        }
                        g.DrawImage(image, 0, 0, thumbSize.Width, thumbSize.Height);
                        // Create memory stream from thumbnail
                        memStream = new MemoryStream();
                        thumb.Save(memStream, imageFormat);
                        image.Dispose();
                        thumb.Dispose();
                        // Save thumbnail to cache
                        if (enableCaching)
                        {
                            imageCache = new ImageCache(contentType, memStream.ToArray());
                            TimeSpan sliding = new TimeSpan(0, Convert.ToInt32(duration), 0);
                            DataCache.SetCache(cacheKey, imageCache, sliding);
                        }
                    }
                    // If an Etag is present and valid
                    if (string.IsNullOrEmpty(headerEtag) == false && headerEtag == eTag)
                    {
                        // Return 304 Not Modified
                        context.Response.Clear();
                        context.Response.StatusCode      = (int)HttpStatusCode.NotModified;
                        context.Response.SuppressContent = true;
                    }
                    else
                    {
                        // Return thumbnail to browser
                        context.Response.StatusCode  = (int)HttpStatusCode.OK;
                        context.Response.ContentType = contentType;
                        if (enableCaching)
                        {
                            HttpCachePolicy contextCache = context.Response.Cache;
                            contextCache.SetCacheability(HttpCacheability.ServerAndPrivate);
                            contextCache.SetExpires(DateTime.Now.AddMinutes(minutes).ToUniversalTime());
                            contextCache.SetLastModified(DateTime.Now.ToUniversalTime());
                            contextCache.SetETag(eTag);
                        }
                        memStream.WriteTo(context.Response.OutputStream);
                    }
                    memStream.Close();
                    memStream.Dispose();
                }
            }
            catch
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
            }
        }
예제 #8
0
        public void Deny_Unrestricted()
        {
            HttpCachePolicy cache = response.Cache;

            Assert.IsNotNull(cache.VaryByHeaders, "VaryByHeaders");
            Assert.IsNotNull(cache.VaryByParams, "VaryByParams");
            cache.AddValidationCallback(new HttpCacheValidateHandler(Validate), null);
            cache.AppendCacheExtension("mono");
            cache.SetCacheability(HttpCacheability.NoCache);
            cache.SetCacheability(HttpCacheability.NoCache, "mono");
            cache.SetETag("etag");
            try
            {
                cache.SetETagFromFileDependencies();
            }
            catch (TypeInitializationException)
            {
                // 1.1 tries to initialize HttpRuntime
            }
            catch (InvalidOperationException)
            {
                // expected
            }
            cache.SetExpires(DateTime.MinValue);
            cache.SetLastModified(DateTime.Now);
            try
            {
                cache.SetLastModifiedFromFileDependencies();
            }
            catch (InvalidOperationException)
            {
                // expected
            }
            catch (NotImplementedException)
            {
                // mono
            }
            cache.SetMaxAge(TimeSpan.FromTicks(1000));
            try
            {
                cache.SetNoServerCaching();
            }
            catch (NotImplementedException)
            {
                // mono
            }
            try
            {
                cache.SetNoStore();
            }
            catch (NotImplementedException)
            {
                // mono
            }
            try
            {
                cache.SetNoTransforms();
            }
            catch (NotImplementedException)
            {
                // mono
            }
            cache.SetProxyMaxAge(TimeSpan.FromTicks(2000));
            cache.SetRevalidation(HttpCacheRevalidation.None);
            cache.SetSlidingExpiration(true);
            try
            {
                cache.SetValidUntilExpires(true);
            }
            catch (NotImplementedException)
            {
                // mono
            }
            cache.SetVaryByCustom("custom");
            cache.SetAllowResponseInBrowserHistory(true);

#if NET_2_0
            try
            {
                cache.SetOmitVaryStar(false);
            }
            catch (NotImplementedException)
            {
                // mono
            }
#endif
        }
예제 #9
0
        internal static void ProcessRequestInternal(HttpContext context, string pathOverride)
        {
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;

            string physicalPath = context.Request.PhysicalPath;
            string fileName     = Path.GetFileName(physicalPath);

            if (pathOverride != null)
            {
                physicalPath = pathOverride;
            }

            FileInfo info;

            if (!FileExists(physicalPath))
            {
                string error = "File does not exist";
                if (context.IsDebuggingEnabled)
                {
                    error += String.Format(": {0}", physicalPath);
                }
                throw new HttpException(404, error);
            }

            try
            {
                info = new FileInfo(physicalPath);
            }
            catch (IOException exception)
            {
                throw new HttpException(404, "Error trying to enumerate files", exception);
            }
            catch (SecurityException exception2)
            {
                throw new HttpException(401, "File enumerator access denied", exception2);
            }

            if (info.Length == 0)
            {
                throw new HttpException(404, "File is empty");
            }

            if ((info.Attributes & FileAttributes.Hidden) != 0)
            {
                throw new HttpException(404, "File is hidden");
            }

            if (physicalPath[physicalPath.Length - 1] == '.')
            {
                throw new HttpException(404, "File does not exist");
            }

            if ((info.Attributes & FileAttributes.Directory) != 0)
            {
                if (request.Path.EndsWith("/"))
                {
                    throw new HttpException(403, SR.GetString("Missing star mapping"));
                }
                response.Redirect(request.Path + "/");
            }
            else
            {
                DateTime lastModTime = new DateTime(info.LastWriteTime.Year, info.LastWriteTime.Month, info.LastWriteTime.Day, info.LastWriteTime.Hour, info.LastWriteTime.Minute, info.LastWriteTime.Second, 0);

                if (lastModTime > DateTime.Now)
                {
                    lastModTime = DateTime.Now;
                }

                string strETag = GenerateETag(context, lastModTime);

                try
                {
                    BuildFileItemResponse(context, physicalPath, info.Length, lastModTime, strETag);
                }
                catch (Exception exception3)
                {
                    if ((exception3 is ExternalException) && IsSecurityError(((ExternalException)exception3).ErrorCode))
                    {
                        throw new HttpException(401, "Resource access forbidden");
                    }
                }

                // set cache headers
                HttpCachePolicy cachePolicy = context.Response.Cache;
                SetCachingPolicy(cachePolicy);

                // set cache file info
                cachePolicy.SetETag(strETag);
                cachePolicy.SetLastModified(lastModTime);
            }
        }
예제 #10
0
        /// <summary>
        /// This will make the browser and server keep the output
        /// in its cache and thereby improve performance.
        /// See http://en.wikipedia.org/wiki/HTTP_ETag
        /// </summary>
        /// <param name="path">
        /// The combined path to the items.
        /// </param>
        /// <param name="context">
        /// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that provides
        /// references to the intrinsic server objects
        /// </param>
        /// <param name="responseType">
        /// The HTTP MIME type to to send.
        /// </param>
        /// <param name="futureExpire">
        /// Whether the response headers should be set to expire in the future.
        /// </param>
        /// <param name="fileMonitors">
        /// The file Monitors.
        /// </param>
        protected void SetHeaders(string path, HttpContext context, ResponseType responseType, bool futureExpire, IList <string> fileMonitors)
        {
            // Generate a hash from the combined last write times of any monitors and
            // the path.
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append(path);

            if (fileMonitors != null)
            {
                foreach (string fileMonitor in fileMonitors)
                {
                    FileInfo fileInfo = new FileInfo(fileMonitor);
                    stringBuilder.AppendFormat("{0}", fileInfo.LastWriteTimeUtc);
                }
            }

            int hash = stringBuilder.ToString().GetHashCode();

            HttpResponse    response = context.Response;
            HttpCachePolicy cache    = response.Cache;

            response.ContentType = responseType.ToDescription();
            cache.VaryByHeaders["Accept-Encoding"] = true;

            if (futureExpire)
            {
                int maxCacheDays = CruncherConfiguration.Instance.MaxCacheDays;

                cache.SetExpires(DateTime.UtcNow.AddDays(maxCacheDays));
                cache.SetMaxAge(new TimeSpan(maxCacheDays, 0, 0, 0));
                if (fileMonitors != null)
                {
                    response.AddFileDependencies(fileMonitors.ToArray());
                    cache.SetLastModifiedFromFileDependencies();
                }

                cache.SetValidUntilExpires(false);
            }
            else
            {
                cache.SetExpires(DateTime.UtcNow.AddDays(-1));
                cache.SetMaxAge(new TimeSpan(0, 0, 0, 0));
            }

            cache.SetRevalidation(HttpCacheRevalidation.AllCaches);

            string etag         = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", hash);
            string incomingEtag = context.Request.Headers["If-None-Match"];

            cache.SetETag(etag);
            cache.SetCacheability(HttpCacheability.Public);

            if (string.Compare(incomingEtag, etag, StringComparison.Ordinal) != 0)
            {
                return;
            }

            response.Clear();
            response.StatusCode      = (int)HttpStatusCode.NotModified;
            response.SuppressContent = true;
        }
예제 #11
0
        /// <summary>
        /// Configures ASP.Net's Cache policy based on properties set
        /// </summary>
        /// <param name="policy">cache policy to set</param>
        void ICachePolicyConfigurer.Configure(HttpCachePolicy policy)
        {
            policy.SetAllowResponseInBrowserHistory(allowInHistory);
            policy.SetCacheability(cacheability);
            policy.SetOmitVaryStar(omitVaryStar);
            policy.SetRevalidation(revalidation);
            policy.SetSlidingExpiration(slidingExpiration);
            policy.SetValidUntilExpires(validUntilExpires);

            if (duration != 0)
            {
                policy.SetExpires(DateTime.Now.AddSeconds(duration));
            }

            if (varyByContentEncodings != null)
            {
                foreach (var header in varyByContentEncodings.Split(','))
                {
                    policy.VaryByContentEncodings[header.Trim()] = true;
                }
            }

            if (varyByCustom != null)
            {
                policy.SetVaryByCustom(varyByCustom);
            }

            if (varyByHeaders != null)
            {
                foreach (var header in varyByHeaders.Split(','))
                {
                    policy.VaryByHeaders[header.Trim()] = true;
                }
            }

            if (varyByParams != null)
            {
                foreach (var param in varyByParams.Split(','))
                {
                    policy.VaryByParams[param.Trim()] = true;
                }
            }

            if (cacheExtension != null)
            {
                policy.AppendCacheExtension(cacheExtension);
            }

            if (setEtagFromFileDependencies)
            {
                policy.SetETagFromFileDependencies();
            }

            if (setLastModifiedFromFileDependencies)
            {
                policy.SetLastModifiedFromFileDependencies();
            }

            if (setNoServerCaching)
            {
                policy.SetNoServerCaching();
            }

            if (setNoStore)
            {
                policy.SetNoStore();
            }

            if (setNoTransforms)
            {
                policy.SetNoTransforms();
            }

            if (etag != null)
            {
                policy.SetETag(etag);
            }

            if (isLastModifiedSet)
            {
                policy.SetLastModified(lastModified);
            }

            if (isMaxAgeSet)
            {
                policy.SetMaxAge(TimeSpan.FromSeconds(maxAge));
            }

            if (isProxyMaxAgeSet)
            {
                policy.SetProxyMaxAge(TimeSpan.FromSeconds(proxyMaxAge));
            }
        }
 public override void SetETag(string etag)
 {
     _policy.SetETag(etag);
 }
예제 #13
0
        public void ProcessRequest(HttpContext context)
        {
            HttpRequest request     = context.Request;
            string      phyFilePath = request.PhysicalPath;

            if (!File.Exists(phyFilePath))
            {
                string phyDirPath = Path.GetDirectoryName(phyFilePath);
                if (!string.IsNullOrWhiteSpace(phyDirPath))
                {
                    string fileName = Path.GetFileNameWithoutExtension(phyFilePath);
                    if (!string.IsNullOrWhiteSpace(fileName))
                    {
                        string fileExtension = Path.GetExtension(phyFilePath);
                        if (!string.IsNullOrWhiteSpace(fileExtension))
                        {
                            string[] fileNames = fileName.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
                            if (fileNames != null)
                            {
                                int length = fileNames.Length;
                                if (length > 1)
                                {
                                    fileName    = string.Join("_", fileNames, 0, length - 1);
                                    phyFilePath = Path.Combine(phyDirPath, string.Concat(fileName, fileExtension));
                                }
                                Array.Clear(fileNames, 0, length);
                                fileNames = null;
                            }
                            fileExtension = null;
                        }
                        fileName = null;
                    }
                    phyDirPath = null;
                }
            }
            if (File.Exists(phyFilePath))
            {
                HttpResponse response  = context.Response;
                ECacheType   cacheType = ECacheType.None;
                string       subfix    = Path.GetExtension(phyFilePath);
                if (".css".Equals(subfix, StringComparison.CurrentCultureIgnoreCase))
                {
                    cacheType            = ECacheType.Css;
                    response.ContentType = "text/css";
                }
                else if (".js".Equals(subfix, StringComparison.CurrentCultureIgnoreCase))
                {
                    cacheType            = ECacheType.Js;
                    response.ContentType = "application/x-javascript";
                }
#if !DEBUG
                if (cacheType != ECacheType.None)
                {
                    //http://www.cnblogs.com/shanyou/archive/2012/05/01/2477500.html
                    const int DAYS            = 30;
                    string    ifModifiedSince = request.Headers["If-Modified-Since"];
                    if (!string.IsNullOrEmpty(ifModifiedSince) &&
                        TimeSpan.FromTicks(DateTime.Now.Ticks - DateTime.Parse(ifModifiedSince).Ticks).Days < DAYS)
                    {
                        response.StatusCode        = (int)System.Net.HttpStatusCode.NotModified;
                        response.StatusDescription = "Not Modified";
                        response.End();
                        return;
                    }
                    else
                    {
                        string fileContent = null;
                        string ifNoneMatch = request.Headers["If-None-Match"];
                        string eTag        = string.Format("\"{0}\"", this.GetFileMd5(string.Concat(phyFilePath, fileContent = this.GetFileContent(phyFilePath))));
                        if (!string.IsNullOrEmpty(ifNoneMatch) && ifNoneMatch.Equals(eTag))
                        {
                            response.StatusCode        = (int)System.Net.HttpStatusCode.NotModified;
                            response.StatusDescription = "Not Modified";
                            response.End();
                            return;
                        }
                        else
                        {
                            HttpCachePolicy cache = response.Cache;
                            //cache.SetLastModifiedFromFileDependencies();//程序自动读取文件的LastModified
                            cache.SetLastModified(context.Timestamp); //因为静态文件的URL是特殊处理过,所以程序自动读取文件是在磁盘上找不到的,故改成手工代码设置文件的LastModified的方式。wangyunpeng,2016-4-12
                            //cache.SetETagFromFileDependencies();//程序自动读取文件的ETag
                            cache.SetETag(eTag);                      //因为静态文件的URL是特殊处理过,所以程序自动读取文件是在磁盘上找不到的,故改成手工代码设置文件的ETag的方式。wangyunpeng,2016-4-12
                            cache.SetCacheability(HttpCacheability.Public);
                            cache.SetExpires(DateTime.Now.AddDays(DAYS));
                            TimeSpan timeSpan = TimeSpan.FromDays(DAYS);
                            cache.SetMaxAge(timeSpan);
                            cache.SetProxyMaxAge(timeSpan);
                            cache.SetValidUntilExpires(true);
                            cache.SetSlidingExpiration(true);
                            #region 压缩js和css文件
                            if (!string.IsNullOrWhiteSpace(fileContent))
                            {
                                if (cacheType == ECacheType.Js)
                                {
                                    string fileName = Path.GetFileName(phyFilePath);
                                    if (_MiniJsFiles.Contains(fileName, new StringComparer()))
                                    {
                                        fileContent = this.PackJavascript(fileContent);//ECMAScript压缩
                                    }
                                }
                                //输出内容
                                response.ContentEncoding = _GlobalizationSection == null ? Encoding.UTF8 : _GlobalizationSection.ResponseEncoding;
                                response.Write(fileContent);
                            }
                            #endregion
                        }
                    }
                }
                else
                {//直接输出文件
                    response.WriteFile(phyFilePath);
                }
#else
                //直接输出文件
                response.WriteFile(phyFilePath);
#endif
                //取消GZIP压缩,IE7,IE8,Safari支持GZIP压缩显示css和js有问题。wangyunpeng
                if (this.IsAcceptEncoding(request, GZIP))
                {
                    response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                    this.SetResponseEncoding(response, GZIP);
                }
                else if (this.IsAcceptEncoding(request, DEFLATE))
                {
                    response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                    this.SetResponseEncoding(response, DEFLATE);
                }
                response.End();
            }
        }