IHttphandler之防止图片盗链

同样IHttpHandler原理见“IHttphandler子Url重写”一文。

web.config设置如下:

<httpHandlers>
      <add verb="*" path="*.gif" type="MyHttpHandler.PreventAntiLeechHandler,MyHttpHandler"/>    </httpHandlers>

如果请求的路径为gif图片(*.gif)则经过MyHttpHandler.PreventAntiLeechHandler处理后返回。

PreventAntiLeechHandler实现如下:

 

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Web;
using  System.Web.UI;
using  System.Drawing;
using  System.IO;

namespace  MyHttpHandler
{
    
class  PreventAntiLeechHandler : IHttpHandler
    {
        
#region  IHttpHandler 成员

        
public   bool  IsReusable
        {
            
get  {  return   false ; }
        }

        
public   void  ProcessRequest(HttpContext context)
        {
            
if  (context.Request.Url.Authority  ==  context.Request.UrlReferrer.Authority)
            {
                CommonDeal.DealImageRequest(context);
            }
            
else
            {
                CommonDeal.ReturnErrorImage(context);
            }
        }

        
#endregion
    }
}

CommonDeal实现如下:

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Web;
using  System.Web.UI;
using  System.IO;
using  System.Drawing;
using  System.Drawing.Imaging;

namespace  MyHttpHandler
{
    
internal   class  CommonDeal
    {
        
public   static   void  DealImageRequest(HttpContext context)
        {
            Font titleFont 
=   new  Font( " 黑体 " 12 , FontStyle.Bold); // 标题字体 
            Font font  =   new  Font( " Consolas " 8 , FontStyle.Regular); // 数字0字有斜线的字体:WST_Ital,  01 DigitGraphics , 00 Starmap Truetype,Consolas,
            
// Font font = new Font("WST_Engl", 8); // 正文字体 
            Font headerFont  =   new  Font( " 黑体 " 12 , FontStyle.Bold); // 列名标题 
            Font footerFont  =   new  Font( " Arial " 8 ); // 页脚显示页数的字体 
            Font upLineFont  =   new  Font( " Arial " 9 , FontStyle.Bold); // 当header分两行显示的时候,上行显示的字体。 
            Font underLineFont  =   new  Font( " Arial " 8 ); // 当header分两行显示的时候,下行显示的字
            Font enFont  =   new  Font( " Times New Roman " 12 );

            MemoryStream ms 
=   new  MemoryStream();

            
string  filePath  =  context.Server.MapPath( " Image "   +  context.Request.Path);
            
try
            {
                Image image 
=  Image.FromFile(filePath);
                
if  (IsPixelFormatIndexed(image.PixelFormat))
                {
                    Bitmap bmp 
=   new  Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
                    
using  (Graphics graphic  =  Graphics.FromImage(bmp))
                    {
                        graphic.InterpolationMode 
=  System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                        graphic.SmoothingMode 
=  System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                        graphic.CompositingQuality 
=  System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                        graphic.DrawImage(image, 
0 0 );
                        graphic.DrawString(
" pangxiaoliang " , enFont,  new  SolidBrush(Color.LightGray),  2 2 );
                        graphic.DrawString(
" pangxiaoliang " , enFont,  new  SolidBrush(Color.Black),  0 0 );

                    }
                    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                    bmp.Dispose();
                }
                
else
                {
                    
using  (Graphics graphic  =  Graphics.FromImage(image))
                    {
                        graphic.DrawString(
" pangxiaoliang " , enFont,  new  SolidBrush(Color.LightGray),  2 2 );
                        graphic.DrawString(
" pangxiaoliang " , enFont,  new  SolidBrush(Color.Black),  0 0 );

                    }

                    Bitmap theBitmap 
=   new  Bitmap(image);
                    theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    theBitmap.Dispose();
                }

                context.Response.ClearContent();
                context.Response.ContentType 
=   " image/jpg " ;
                context.Response.BinaryWrite(ms.ToArray());

            }
            
catch
            {
                Bitmap error 
=   new  Bitmap(context.Server.MapPath( " Image/error.bmp " ));
                error.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                error.Dispose();
                context.Response.ClearContent();
                context.Response.ContentType 
=   " image/jpg " ;
                context.Response.BinaryWrite(ms.ToArray());
            }
            
finally
            {
                ms.Close();
                ms.Dispose();
                context.Response.End();
            }
        }

        
public   static   void  ReturnErrorImage(HttpContext context)
        {
            MemoryStream ms 
=   new  MemoryStream();
            
try
            {
                Bitmap error 
=   new  Bitmap(context.Server.MapPath( " error.bmp " ));
                error.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                error.Dispose();
                context.Response.ClearContent();
                context.Response.ContentType 
=   " image/jpg " ;
                context.Response.BinaryWrite(ms.ToArray());
            }
            
catch
            {
            }
            
finally
            {
                ms.Close();
                ms.Dispose();
                context.Response.End();
            }
        }

        
///   <summary>
        
///  会产生graphics异常的PixelFormat
        
///   </summary>
         private   static  PixelFormat[] indexedPixelFormats  =  { PixelFormat.Undefined, PixelFormat.DontCare,
                                            PixelFormat.Format16bppArgb1555, PixelFormat.Format1bppIndexed, PixelFormat.Format4bppIndexed,
                                            PixelFormat.Format8bppIndexed
                                            };

        
///   <summary>
        
///  判断图片的PixelFormat 是否在 引发异常的 PixelFormat 之中
        
///   </summary>
        
///   <param name="imgPixelFormat"> 原图片的PixelFormat </param>
        
///   <returns></returns>
         private   static   bool  IsPixelFormatIndexed(PixelFormat imgPixelFormat)
        {
            
foreach  (PixelFormat pf  in  indexedPixelFormats)
            {
                
if  (pf.Equals(imgPixelFormat))  return   true ;
            }

            
return   false ;
        }
    }


}

防止盗链关键点在:

if (context.Request.Url.Authority == context.Request.UrlReferrer.Authority)
{
      CommonDeal.DealImageRequest(context);
}
else
{
      CommonDeal.ReturnErrorImage(context);
}

客户端请求gif图像路径“http://localhost:2868/Image/logo.gif”,则:

1)如果是本站内请求

context.Request.Url.Authority是请求的地址,即“http://localhost:2868”。

context.Request.UrlReferrer.Authority是引用地址(请求的站点),即“http://localhost:2868”。

所以此时返回客户端的是带有水印的正确图像。

2)如果是其他站盗链(“http://localhost:9999”)

context.Request.Url.Authority是请求的地址,即“http://localhost:2868”。

context.Request.UrlReferrer.Authority是引用地址(请求的站点),即“http://localhost:9999”。

所以此时返回客户端的是提示请勿盗链图像。

 

你可能感兴趣的:(handler)