原理就是利用了IIS中HttpHandler模块来处理的。因为比如
平时用IIS只是处理如asp,aspx等文件,没处理如iis,jpg等图片的,下面简单小结下
1 建一个网站(vs.net 2005),然后添加一个Handler.ashx处理文件,处理HTTP请求,代码如下
平时用IIS只是处理如asp,aspx等文件,没处理如iis,jpg等图片的,下面简单小结下
1 建一个网站(vs.net 2005),然后添加一个Handler.ashx处理文件,处理HTTP请求,代码如下
<%
@ WebHandler Language
=
"
C#
"
Class
=
"
Handler
"
%>
using System;
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
// 判断是否是本地引用,如果是则返回给客户端正确的图片
// 这里的判断就是用到了http请求中所记录的页信息
// 如果是网站,可将“localhost”修改为网站地址
if (context.Request.UrlReferrer.Host == " localhost " )
{
// 设置客户端缓冲中文件过期时间为0,即立即过期。
context.Response.Expires = 0 ;
// 清空服务器端为此会话开辟的输出缓存
context.Response.Clear();
// 获得文件类型
context.Response.ContentType = " image/jpg " ;
// 将请求文件写入到输出缓存中
context.Response.WriteFile(context.Request.PhysicalPath);
// 将输出缓存中的信息传送到客户端
context.Response.End();
}
// 如果不是本地引用,则属于盗链引用,返回给客户端错误的图片
else
{
// 设置客户端缓冲中文件过期时间为0,即立即过期。
context.Response.Expires = 0 ;
// 清空服务器端为此会话开辟的输出缓存
context.Response.Clear();
// 获得文件类型
context.Response.ContentType = " image/jpg " ;
// 将特殊的报告错误的图片文件写入到输出缓存中
context.Response.WriteFile(context.Request.PhysicalApplicationPath + " error.jpg " );
// 将输出缓存中的信息传送到客户端
context.Response.End();
}
}
public bool IsReusable
{
get
{
return true ;
}
}
}
using System;
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
// 判断是否是本地引用,如果是则返回给客户端正确的图片
// 这里的判断就是用到了http请求中所记录的页信息
// 如果是网站,可将“localhost”修改为网站地址
if (context.Request.UrlReferrer.Host == " localhost " )
{
// 设置客户端缓冲中文件过期时间为0,即立即过期。
context.Response.Expires = 0 ;
// 清空服务器端为此会话开辟的输出缓存
context.Response.Clear();
// 获得文件类型
context.Response.ContentType = " image/jpg " ;
// 将请求文件写入到输出缓存中
context.Response.WriteFile(context.Request.PhysicalPath);
// 将输出缓存中的信息传送到客户端
context.Response.End();
}
// 如果不是本地引用,则属于盗链引用,返回给客户端错误的图片
else
{
// 设置客户端缓冲中文件过期时间为0,即立即过期。
context.Response.Expires = 0 ;
// 清空服务器端为此会话开辟的输出缓存
context.Response.Clear();
// 获得文件类型
context.Response.ContentType = " image/jpg " ;
// 将特殊的报告错误的图片文件写入到输出缓存中
context.Response.WriteFile(context.Request.PhysicalApplicationPath + " error.jpg " );
// 将输出缓存中的信息传送到客户端
context.Response.End();
}
}
public bool IsReusable
{
get
{
return true ;
}
}
}
然后同样建立一个Handler.cs文件,放在app_code目录下,其内容就是上面的handler.aschx了,
2 在web.config中配置如下
<httpHandlers>
<add verb = "*" path = "*.jpg" type="Handler" />
</httpHandlers>
3 在IIS里处理
在IIS里的默认网站的“配置”里,在“应用程序映射”里添加映射
其中映射的可执行文件为 “vs.net2005安装路径/aspnet_isapi.dll",扩展名为".jpg",这样就可以了
下面是一个完整的防盗链类
/*
*
* 防盗链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 ;
}
}
}
}
}
*
* 防盗链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 ;
}
}
}
}
}