同样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”。
所以此时返回客户端的是提示请勿盗链图像。