使用HttpHandler隐藏图片真实地址,轻松实现防盗链
正着手准备做个图片共享网站,考虑到图片的防盗链,剥离出了BlogEngine的ImageHandler,并进行简单地修改。用来做隐藏图片的真实地址和防盗链。
public class ImageHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
if (!string.IsNullOrEmpty(context.Request.QueryString["picture"]))
{
string fileName = context.Request.QueryString["picture"];
OnServing(fileName);
try
{
string folder = "App_Data/Picture/";
FileInfo fi = new FileInfo(context.Server.MapPath(folder) + fileName);
if (fi.Exists &&
fi.Directory.FullName.ToUpperInvariant().Contains(
Path.DirectorySeparatorChar + "PICTURE"))
{
//context.Response.Cache.SetCacheability(HttpCacheability.Public);
//context.Response.Cache.SetExpires(DateTime.Now.AddYears(1));
//if (Utils.SetConditionalGetHeaders(fi.CreationTimeUtc))
// return;
int index = fileName.LastIndexOf(".") + 1;
string extension = fileName.Substring(index).ToUpperInvariant();
// Fix for IE not handling jpg image types
if (string.Compare(extension, "JPG") == 0)
context.Response.ContentType = "image/jpeg";
else
context.Response.ContentType = "image/" + extension;
context.Response.TransmitFile(fi.FullName);
OnServed(fileName);
}
else
{
OnBadRequest(fileName);
context.Response.ContentType = "image/gif";
context.Response.TransmitFile(context.Server.MapPath(folder) + "nophoto.gif");
//context.Response.Redirect(Utils.AbsoluteWebRoot + "error404.aspx");
}
}
catch (Exception ex)
{
OnBadRequest(ex.Message);
//context.Response.Redirect(Utils.AbsoluteWebRoot + "error404.aspx");
}
}
}
/// <summary>
/// Occurs before the requested image is served.
/// </summary>
public static event EventHandler<EventArgs> Serving;
private static void OnServing(string file)
{
if (Serving != null)
{
Serving(file, EventArgs.Empty);
}
}
/// <summary>
/// Occurs when a file is served.
/// </summary>
public static event EventHandler<EventArgs> Served;
private static void OnServed(string file)
{
if (Served != null)
{
Served(file, EventArgs.Empty);
}
}
/// <summary>
/// Occurs when the requested file does not exist.
/// </summary>
public static event EventHandler<EventArgs> BadRequest;
private static void OnBadRequest(string file)
{
if (BadRequest != null)
{
BadRequest(file, EventArgs.Empty);
}
}
}
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
if (!string.IsNullOrEmpty(context.Request.QueryString["picture"]))
{
string fileName = context.Request.QueryString["picture"];
OnServing(fileName);
try
{
string folder = "App_Data/Picture/";
FileInfo fi = new FileInfo(context.Server.MapPath(folder) + fileName);
if (fi.Exists &&
fi.Directory.FullName.ToUpperInvariant().Contains(
Path.DirectorySeparatorChar + "PICTURE"))
{
//context.Response.Cache.SetCacheability(HttpCacheability.Public);
//context.Response.Cache.SetExpires(DateTime.Now.AddYears(1));
//if (Utils.SetConditionalGetHeaders(fi.CreationTimeUtc))
// return;
int index = fileName.LastIndexOf(".") + 1;
string extension = fileName.Substring(index).ToUpperInvariant();
// Fix for IE not handling jpg image types
if (string.Compare(extension, "JPG") == 0)
context.Response.ContentType = "image/jpeg";
else
context.Response.ContentType = "image/" + extension;
context.Response.TransmitFile(fi.FullName);
OnServed(fileName);
}
else
{
OnBadRequest(fileName);
context.Response.ContentType = "image/gif";
context.Response.TransmitFile(context.Server.MapPath(folder) + "nophoto.gif");
//context.Response.Redirect(Utils.AbsoluteWebRoot + "error404.aspx");
}
}
catch (Exception ex)
{
OnBadRequest(ex.Message);
//context.Response.Redirect(Utils.AbsoluteWebRoot + "error404.aspx");
}
}
}
/// <summary>
/// Occurs before the requested image is served.
/// </summary>
public static event EventHandler<EventArgs> Serving;
private static void OnServing(string file)
{
if (Serving != null)
{
Serving(file, EventArgs.Empty);
}
}
/// <summary>
/// Occurs when a file is served.
/// </summary>
public static event EventHandler<EventArgs> Served;
private static void OnServed(string file)
{
if (Served != null)
{
Served(file, EventArgs.Empty);
}
}
/// <summary>
/// Occurs when the requested file does not exist.
/// </summary>
public static event EventHandler<EventArgs> BadRequest;
private static void OnBadRequest(string file)
{
if (BadRequest != null)
{
BadRequest(file, EventArgs.Empty);
}
}
}
备注:不太明白这里的private static void OnServing(string file),private static void OnServed(string file),private static void OnBadRequest(string file)这些方法以及事件的作用,还请网友们不吝赐教。
如果要实现防盗链,只需要加入对Request.UrlReferrer.Host的判断就OK了。
在Web.config中加入:
<httpHandlers>
<add verb="*" path="image.axd" type="MzMobile.Web.HttpHandlers.ImageHandler, MzMobile.Web" validate="false"/>
</httpHandlers>
<add verb="*" path="image.axd" type="MzMobile.Web.HttpHandlers.ImageHandler, MzMobile.Web" validate="false"/>
</httpHandlers>
这样,在App_Data文件夹中创建"Picture"目录,并在目录下存放图片文件,这样就可以用image.axd?picture=PictureName (PictureName指你的图片名称)来访问图片了。
BlogEngine有太多值得学习的地方了,好东西啊!