一颗不安分的创业心

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, 
00);
                        graphic.DrawString(
"pangxiaoliang", enFont, new SolidBrush(Color.LightGray), 22);
                        graphic.DrawString(
"pangxiaoliang", enFont, new SolidBrush(Color.Black), 00);

                    }
                    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), 22);
                        graphic.DrawString(
"pangxiaoliang", enFont, new SolidBrush(Color.Black), 00);

                    }

                    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”。

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

 

posted @ 2009-06-28 16:43  pangxiaoliang[北京]流浪者  阅读(299)  评论(0编辑  收藏  举报
小豆芽之父