/*
*
*防盗链IHttpHandler
*
*
*增加了对文件关键字的选择(即仅对文件名存在某些关键字或不存在某些关键字进行过滤)
*设置web.config中<appSettings>节以下值
*stringeWebapp_NoLink如果文件名符合该正确表态式将进行过滤(不设置对所有进行过滤)
*stringeWebapp_AllowLink如果文件名符合该正确表态式将不进行过滤(优先权高于AllowLink,不设置则服从AllowLink)
*booleWebapp_AllowOnlyFile如果为False,(默认true)则不允许用户直接对该文件进行访问建议为true
*
*
*:)以下设置均可省略,设置只是为了增加灵活性与体验
*eWebapp_NoLink_Message错误信息提示:默认为LinkFrom:域名
*eWebapp_Error_Width错误信息提示图片宽
*eWebapp_Error_Height错误信息提示图片高
*
*
*
*
*http://ewebapp.net
*/



usingSystem;
usingSystem.Web;
usingSystem.Drawing;
usingSystem.Drawing.Imaging;
usingSystem.IO;
usingSystem.Configuration;
usingSystem.Text.RegularExpressions;

namespaceeWebapp
{
///<summary>
///防盗链IHttpHandler
///参考http://www.softat.org/archiver/tid-52114.html
///
///</summary>
publicclassNoLink:IHttpHandler
{
privatestringeWebapp_NoLink=string.Empty;
privatestringeWebapp_AllowLink=string.Empty;
privatebooleWebapp_AllowOnlyFile=true;

privatestringeWebapp_NoLink_Message=string.Empty;
privateboolerror=false;

publicNoLink()
{
//
//TODO:在此处添加构造函数逻辑
//
}

publicvoidProcessRequest(HttpContextcontext)
{
eWebapp_NoLink_Message=ConfigurationSettings.AppSettings["eWebapp_NoLink_Message"];


stringmyDomain=string.Empty;

error=errorLink(context,outmyDomain);

if(Empty(eWebapp_NoLink_Message))
{
eWebapp_NoLink_Message="Linkfrom:"+myDomain;
}



if(error)
{
//Jpg(context.Response,eWebapp_NoLink_Message);
Jpg(context.Response,eWebapp_NoLink_Message);
}
else
{
Real(context.Response,context.Request);
}

}

publicboolIsReusable
{
get

{
returntrue;
}
}


///<summary>
///输出错误信息
///</summary>
///<paramname="Response"></param>
///<paramname="_word"></param>
privatevoidJpg(HttpResponseResponse,string_word)
{


intmyErrorWidth=_word.Length*15;
intmyErrorHeight=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
{

}
BitmapImg=null;
Graphicsg=null;
MemoryStreamms=null;
Img=newBitmap(myErrorWidth,myErrorHeight);
g=Graphics.FromImage(Img);
g.Clear(Color.White);
Fontf=newFont("Arial",9);
SolidBrushs=newSolidBrush(Color.Red);
g.DrawString(_word,f,s,3,3);
ms=newMemoryStream();
Img.Save(ms,ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType="image/Gif";
Response.BinaryWrite(ms.ToArray());
g.Dispose();
Img.Dispose();
Response.End();
}

///<summary>
///输出真实文件
///</summary>
///<paramname="response"></param>
///<paramname="context"></param>
privatevoidReal(HttpResponseresponse,HttpRequestrequest)
{
FileInfofile=newSystem.IO.FileInfo(request.PhysicalPath);

response.Clear();

response.AddHeader("Content-Disposition","filename="+file.Name);

response.AddHeader("Content-Length",file.Length.ToString());

stringfileExtension=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>
///<paramname="_value"></param>
///<returns></returns>
privateboolEmpty(string_value)
{
if(_value==null|_value==string.Empty|_value=="")
{
returntrue;
}
else
{
returnfalse;
}
}


///<summary>
///检查是否是非法链接
///</summary>
///<paramname="context"></param>
///<paramname="_myDomain"></param>
///<returns></returns>
privateboolerrorLink(HttpContextcontext,outstring_myDomain)
{
HttpResponseresponse=context.Response;
stringmyDomain=context.Request.ServerVariables["SERVER_NAME"];
_myDomain=myDomain;
stringmyDomainIp=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或域名
stringreferDomain=context.Request.UrlReferrer.AbsoluteUri.Replace(context.Request.UrlReferrer.AbsolutePath,"");
stringmyPath=context.Request.RawUrl;

if(referDomain.IndexOf(myDomainIp)>=0|referDomain.IndexOf(myDomain)>=0)
{
returnfalse;
}
else
{
//这里使用正则表达对规则进行匹配
try
{
RegexmyRegex;

//检查允许匹配
if(!Empty(eWebapp_AllowLink))
{

myRegex=newRegex(eWebapp_AllowLink);

if(myRegex.IsMatch(myPath))
{
returnfalse;
}

}


//检查禁止匹配
if(!Empty(eWebapp_NoLink))
{

myRegex=newRegex(eWebapp_NoLink);
if(myRegex.IsMatch(myPath))
{
returntrue;
}
else
{
returnfalse;
}

}

returntrue;

}
catch
{
//如果匹配出错,链接错误
returntrue;
}
}
}
else
{
//是否允许直接访问文件
if(eWebapp_AllowOnlyFile)
{
returnfalse;
}
else
{
returntrue;
}
}

}

}

}

概述

HttpHandler是一个HTTP请求的真正处理中心,也正是在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。

IHttpHandler是什么

IHttpHandler定义了如果要实现一个HTTP请求的处理所必需实现的一些系统约定。HttpHandlerHttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

IHttpHandler如何处理HTTP请求

当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandlerProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。

对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。所谓一个HttpHandlerFactory,所谓一个HttpHandlerFactory,是指当一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。

一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。

防盗链IHttpHandler

1.打开IIS管理,注册ISAPI映射,比如".jpg"等都指向那个ASPNET_ISAPI.dll,在你的c:/windows/microsoft.net/framework/v1.0.3705下面;
注意,不要勾选“检查文件是否存在”的选项。
2.打开你应用中的web.config,在system.web节中添加如下的话语:

<httpHandlers>
<add verb="*" path="*.jpg" type="IHTTPHandler实现的类, 该类所在的程序集" />
</httpHandlers>
3.编写那个IHttpHandler类:
在ProcessRequest里面根据需要使用context.Response.BinaryWrite将图片的二进制数据打出去就可以了.

相关文章: