⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csshandler.cs

📁 个人博客系统
💻 CS
字号:
#region Using

using System;
using System.Net;
using System.Web;
using System.IO;
using System.Text.RegularExpressions;
using System.IO.Compression;
using System.Web.Caching;

#endregion

namespace BlogEngine.Core.Web.HttpHandlers
{
  /// <summary>
  /// Removes whitespace in all stylesheets added to the 
  /// header of the HTML document in site.master. 
  /// </summary>
  public class CssHandler : IHttpHandler
  {
    /// <summary>
    /// Enables processing of HTTP Web requests by a custom 
    /// HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides 
    /// references to the intrinsic server objects 
    /// (for example, Request, Response, Session, and Server) used to service HTTP requests.
    /// </param>
    public void ProcessRequest(HttpContext context)
    {
      string file = context.Server.MapPath(Utils.RelativeWebRoot + "themes/" + BlogSettings.Instance.Theme + "/" + context.Request.QueryString["name"]);
      ReduceCss(file, context);
      SetHeaders(file, context);

      if (BlogSettings.Instance.EnableHttpCompression)
        Compress(context);
    }

    /// <summary>
    /// Removes all unwanted text from the CSS file,
    /// including comments and whitespace.
    /// </summary>
    private static void ReduceCss(string file, HttpContext context)
    {
      if (!file.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
      {
        throw new System.Security.SecurityException("No access");
      }

      if (context.Cache[file + "date"] == null)
      {
        FileInfo fi = new FileInfo(file);
        using (StreamReader reader = fi.OpenText())
        {
          string body = StripWhitespace(reader);
          context.Cache.Insert(file, body, new CacheDependency(file));
          context.Cache.Insert(file + "date", fi.LastWriteTime, new CacheDependency(file));
        }
      }

      context.Response.Write((string)context.Cache[file]);
    }

    /// <summary>
    /// Strips the whitespace from any .css file.
    /// </summary>
    private static string StripWhitespace(StreamReader reader)
    {
      string body = reader.ReadToEnd();

      body = body.Replace("  ", String.Empty);
      body = body.Replace(Environment.NewLine, String.Empty);
      body = body.Replace("\t", string.Empty);
      body = body.Replace(" {", "{");
      body = body.Replace(" :", ":");
      body = body.Replace(": ", ":");
      body = body.Replace(", ", ",");
      body = body.Replace("; ", ";");
      body = body.Replace(";}", "}");
      //body = Regex.Replace(body, @"/\*[^\*]*\*+([^/\*]*\*+)*/", "$1");
      body = Regex.Replace(body, @"(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,}(?=&nbsp;)|(?<=&ndsp;)\s{2,}(?=[<])", String.Empty);

      return body;
    }

    /// <summary>
    /// This will make the browser and server keep the output
    /// in its cache and thereby improve performance.
    /// </summary>
    private static void SetHeaders(string file, HttpContext context)
    {
      context.Response.ContentType = "text/css";
      context.Response.Cache.VaryByHeaders["Accept-Encoding"] = true;

      DateTime date = (DateTime)context.Cache[file + "date"];
      string etag = "\"" + date.GetHashCode() + "\"";
      string incomingEtag = context.Request.Headers["If-None-Match"];

      context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(7));
      context.Response.Cache.SetCacheability(HttpCacheability.Public);
      //context.Response.Cache.SetLastModified(date);
      context.Response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
      context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
      context.Response.Cache.SetETag(etag);

      if (String.Compare(incomingEtag, etag) == 0)
      {
        context.Response.StatusCode = (int)HttpStatusCode.NotModified;
        context.Response.End();
      }
    }

    #region Compression

    private const string GZIP = "gzip";
    private const string DEFLATE = "deflate";

    private static void Compress(HttpContext context)
    {
      if (context.Request.UserAgent != null && context.Request.UserAgent.Contains("MSIE 6"))
        return;

      if (IsEncodingAccepted(GZIP))
      {
        context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
        SetEncoding(GZIP);
      }
      else if (IsEncodingAccepted(DEFLATE))
      {
        context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
        SetEncoding(DEFLATE);
      }
    }

    /// <summary>
    /// Checks the request headers to see if the specified
    /// encoding is accepted by the client.
    /// </summary>
    private static bool IsEncodingAccepted(string encoding)
    {
      return HttpContext.Current.Request.Headers["Accept-encoding"] != null && HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
    }

    /// <summary>
    /// Adds the specified encoding to the response headers.
    /// </summary>
    /// <param name="encoding"></param>
    private static void SetEncoding(string encoding)
    {
      HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
    }

    #endregion

    /// <summary>
    /// Gets a value indicating whether another request can use the <see cref="T:System.Web.IHttpHandler"></see> instance.
    /// </summary>
    /// <value></value>
    /// <returns>true if the <see cref="T:System.Web.IHttpHandler"></see> instance is reusable; otherwise, false.</returns>
    public bool IsReusable
    {
      get { return false; }
    }

  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -