本文地址:http://qzone.qq.com/blog/101766959-1217965179

/*
*
* 防盜鏈IHttpHandler
*
*
* 增加了對檔關鍵字的選擇(即僅對檔案名存在某些關鍵字或不存在某些關鍵字進行過濾)
* 設置web.config中<appSettings>節以下值
* string eWebapp_NoLink 如果檔案名符合該正確表態式將進行過濾(不設置對所有進行過濾)
* string eWebapp_AllowLink 如果檔案名符合該正確表態式將不進行過濾(優先權高於AllowLink,不設置則服從AllowLink)
* bool eWebapp_ AllowOnlyFile 如果為False,(默認true)則不允許用戶直接對該檔進行訪問建議為true
*
*
* :)以下設置均可省略,設置只是為了增加靈活性與體驗
* eWebapp_NoLink_Message 錯誤資訊提示:默認為Link From:功能變數名稱
* eWebapp_Error_Width 錯誤資訊提示圖片寬
* eWebapp_Error_Height 錯誤資訊提示圖片高
*
*
*
* 垃圾豬 2005-9-11 創建
* http://ewebapp.net
*/
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Configuration;
using System.Text.RegularExpressions;
namespace eWebapp
{
     /// <summary>
     /// 防盜鏈IHttpHandler
     /// 參考http://www.softat.org/archiver/tid-52114.html
     /// 垃圾豬 2005-9-12 修正
     /// </summary>
     public class NoLink : IHttpHandler
     {
         private string eWebapp_NoLink = string.Empty;
         private string eWebapp_AllowLink = string.Empty;
         private bool eWebapp_AllowOnlyFile = true;
         private string eWebapp_NoLink_Message = string.Empty;
         private bool error = false;
         public NoLink()
         {
             //
             // TODO: 在此處添加構造函數邏輯
             //
         }
         public void ProcessRequest(HttpContext context)
         {
             eWebapp_NoLink_Message = ConfigurationSettings.AppSettings["eWebapp_NoLink_Message"];
             string myDomain = string.Empty;
             error = errorLink(context, out myDomain);
             if (Empty(eWebapp_NoLink_Message))
             {
                 eWebapp_NoLink_Message = "Link from :" + myDomain;
             }
             if (error)
             {
                 //Jpg(context.Response,eWebapp_NoLink_Message);
                 Jpg(context.Response, eWebapp_NoLink_Message);
             }
             else
             {
                 Real(context.Response, context.Request);
             }
         }
         public bool IsReusable
         {
             get
             {
                 return true;
             }
         }
         /// <summary>
         /// 輸出錯誤資訊
         /// </summary>
         /// <param name="Response"></param>
         /// <param name="_word"></param>
         private void Jpg(HttpResponse Response, string _word)
         {
             int myErrorWidth = _word.Length * 15;
             int myErrorHeight = 16;
             try
             {
                 int _myErrorWidth = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Width"]);
                 if (_myErrorWidth > 0)
                 {
                     myErrorWidth = _myErrorWidth;
                 }
             }
             catch
             {
             }
             try
             {
                 int _myErrorHeight = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Height"]);
                 if (_myErrorHeight > 0)
                 {
                     myErrorHeight = _myErrorHeight;
                 }
             }
             catch
             {
             }
             Bitmap Img = null;
             Graphics g = null;
             MemoryStream ms = null;
             Img = new Bitmap(myErrorWidth, myErrorHeight);
             g = Graphics.FromImage(Img);
             g.Clear(Color.White);
             Font f = new Font("Arial", 9);
             SolidBrush s = new SolidBrush(Color.Red);
             g.DrawString(_word, f, s, 3, 3);
             ms = new MemoryStream();
             Img.Save(ms, ImageFormat.Jpeg);
             Response.ClearContent();
             Response.ContentType = "image/Gif";
             Response.BinaryWrite(ms.ToArray());
             g.Dispose();
             Img.Dispose();
             Response.End();
         }
         /// <summary>
         /// 輸出真實檔
         /// </summary>
         /// <param name="response"></param>
         /// <param name="context"></param>
         private void Real(HttpResponse response, HttpRequest request)
         {
             FileInfo file = new System.IO.FileInfo(request.PhysicalPath);
             response.Clear();
             response.AddHeader("Content-Disposition", "filename=" + file.Name);
             response.AddHeader("Content-Length", file.Length.ToString());
             string fileExtension = file.Extension.ToLower();
             //這裏選擇輸出的檔格式
             //可以參考http://ewebapp.cnblogs.com/articles/234756.html增加對更多檔格式的支持.
             switch (fileExtension)
             {
                 case "mp3":
                     response.ContentType = "audio/mpeg3";
                     break;
                 case "mpeg":
                     response.ContentType = "video/mpeg";
                     break;
                 case "jpg":
                     response.ContentType = "image/jpeg";
                     break;
                 case "bmp":
                     response.ContentType = "image/bmp";
                     break;
                 case "gif":
                     response.ContentType = "image/gif";
                     break;
                 case "doc":
                     response.ContentType = "application/msword";
                     break;
                 case "css":
                     response.ContentType = "text/css";
                     break;
                 default:
                     response.ContentType = "application/octet-stream";
                     break;
             }
             response.WriteFile(file.FullName);
             response.End();
         }
         /// <summary>
         /// 確認字串是否為空
         /// </summary>
         /// <param name="_value"></param>
         /// <returns></returns>
         private bool Empty(string _value)
         {
             if (_value == null | _value == string.Empty | _value == "")
             {
                 return true;
             }
             else
             {
                 return false;
             }
         }
         /// <summary>
         /// 檢查是否是非法鏈結
         /// </summary>
         /// <param name="context"></param>
         /// <param name="_myDomain"></param>
         /// <returns></returns>
         private bool errorLink(HttpContext context, out string _myDomain)
         {
             HttpResponse response = context.Response;
             string myDomain = context.Request.ServerVariables["SERVER_NAME"];
             _myDomain = myDomain;
             string myDomainIp = context.Request.UserHostAddress;
             eWebapp_NoLink = ConfigurationSettings.AppSettings["eWebapp_NoLink"];
             eWebapp_AllowLink = ConfigurationSettings.AppSettings["eWebapp_AllowLink"];
             try
             {
                 eWebapp_AllowOnlyFile = Convert.ToBoolean(ConfigurationSettings.AppSettings["eWebapp_AllowOnlyFile"]);
             }
             catch
             {
                 eWebapp_AllowOnlyFile = true;
             }
             if (context.Request.UrlReferrer != null)
             {
                 //判定referDomain是否存在網站的IP或功能變數名稱
                 string referDomain = context.Request.UrlReferrer.AbsoluteUri.Replace(context.Request.UrlReferrer.AbsolutePath, "");
                 string myPath = context.Request.RawUrl;
                 if (referDomain.IndexOf(myDomainIp) >= 0 | referDomain.IndexOf(myDomain) >= 0)
                 {
                     return false;
                 }
                 else
                 {
                     //這裏使用正則表達對規則進行匹配
                     try
                     {
                         Regex myRegex;
                         //檢查允許匹配
                         if (!Empty(eWebapp_AllowLink))
                         {
                             myRegex = new Regex(eWebapp_AllowLink);
                             if (myRegex.IsMatch(myPath))
                             {
                                 return false;
                             }
                         }
                         //檢查禁止匹配
                         if (!Empty(eWebapp_NoLink))
                         {
                             myRegex = new Regex(eWebapp_NoLink);
                             if (myRegex.IsMatch(myPath))
                             {
                                 return true;
                             }
                             else
                             {
                                 return false;
                             }
                         }
                         return true;
                     }
                     catch
                     {
                         //如果匹配出錯,鏈結錯誤
                         return true;
                     }
                 }
             }
             else
             {
                 //是否允許直接訪問檔
                 if (eWebapp_AllowOnlyFile)
                 {
                     return false;
                 }
                 else
                 {
                     return true;
                 }
             }
         }
     }
}


arrow
arrow
    全站熱搜

    Roger 發表在 痞客邦 留言(0) 人氣()