/*2
* 3
* 防盗链IHttpHandler4
* 5
* 6
* 增加了对文件关键字的选择(即仅对文件名存在某些关键字或不存在某些关键字进行过滤)7
* 设置web.config中<appSettings>节以下值8
* string eWebapp_NoLink 如果文件名符合该正确表态式将进行过滤(不设置对所有进行过滤)9
* string eWebapp_AllowLink 如果文件名符合该正确表态式将不进行过滤(优先权高于AllowLink,不设置则服从AllowLink)10
* booleWebapp_ AllowOnlyFile 如果为False,(默认true)则不允许用户直接对该文件进行访问建议为true11
* 12
* 13
* :)以下设置均可省略,设置只是为了增加灵活性与体验14
* eWebapp_NoLink_Message 错误信息提示:默认为Link From:域名15
* eWebapp_Error_Width 错误信息提示图片宽16
* eWebapp_Error_Height 错误信息提示图片高17
* 18
* 19
* 20
* 垃圾猪 2005-9-11 创建21
* eWebapp@163.com22
* eWebapp.cnblogs.com23
* 24
*/25

26

27
using System;28
using System.Web;29
using System.Drawing;30
using System.Drawing.Imaging;31
using System.IO;32
using System.Configuration;33
using System.Text.RegularExpressions;34

35
namespace eWebapp.NoLink36
{37
/// <summary>38
/// 防盗链IHttpHandler39
/// 40
/// 垃圾猪 2005-9-12 修正41
/// </summary>42
public class IHandler : IHttpHandler43
{44
public IHandler()45
{46
//47
// TODO: 在此处添加构造函数逻辑48
//49
}50

51
private string eWebapp_NoLink = string.Empty;52
private string eWebapp_AllowLink = string.Empty;53
private bool eWebapp_AllowOnlyFile = true;54

55
private string eWebapp_NoLink_Message = string.Empty;56
private bool error = false;57

58
public void ProcessRequest(HttpContext context)59
{60
eWebapp_NoLink_Message = ConfigurationSettings.AppSettings["eWebapp_NoLink_Message"];61
62
63
string myDomain = string.Empty;64

65
error = errorLink(context,out myDomain); 66

67
if(Empty(eWebapp_NoLink_Message)) 68
{69
eWebapp_NoLink_Message = "Link from :" + myDomain;70
}71

72

73

74
if(error)75
{76
//Jpg(context.Response,eWebapp_NoLink_Message);77
Jpg(context.Response,eWebapp_NoLink_Message);78
}79
else80
{81
Real(context.Response,context.Request);82
}83

84
}85

86
public bool IsReusable87
{88
get89

90
{91
return true;92
}93
}94

95

96
/// <summary>97
/// 输出错误信息98
/// </summary>99
/// <param name="Response"></param>100
/// <param name="_word"></param>101
private void Jpg(HttpResponse Response,string _word) 102
{103

104

105
int myErrorWidth = _word.Length*15;106
int myErrorHeight = 16;107
try108
{109
int _myErrorWidth = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Width"]);110
if(_myErrorWidth > 0 )111
{112
myErrorWidth = _myErrorWidth;113
}114

115
}116
catch117
{118

119
}120
try121
{122
int _myErrorHeight = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Height"]);123
if(_myErrorHeight > 0 )124
{125
myErrorHeight = _myErrorHeight;126
}127
}128
catch129
{130

131
}132
Bitmap Img=null;133
Graphics g=null;134
MemoryStream ms=null;135
Img=new Bitmap(myErrorWidth,myErrorHeight);136
g=Graphics.FromImage(Img);137
g.Clear(Color.White);138
Font f=new Font("Arial",9);139
SolidBrush s=new SolidBrush(Color.Red);140
g.DrawString(_word,f,s,3,3);141
ms=new MemoryStream();142
Img.Save(ms,ImageFormat.Jpeg);143
Response.ClearContent(); 144
Response.ContentType="image/Gif";145
Response.BinaryWrite(ms.ToArray());146
g.Dispose();147
Img.Dispose();148
Response.End();149
}150

151
/// <summary>152
/// 输出真实文件153
/// </summary>154
/// <param name="response"></param>155
/// <param name="context"></param>156
private void Real(HttpResponse response,HttpRequest request)157
{158
FileInfo file = new System.IO.FileInfo(request.PhysicalPath);159

160
response.Clear();161

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

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

166
string fileExtension = file.Extension.ToLower();167

168

169
//这里选择输出的文件格式170
//可以参考http://ewebapp.cnblogs.com/articles/234756.html增加对更多文件格式的支持.171

172
173
switch (fileExtension)174
{175

176
case "mp3":177
response.ContentType = "audio/mpeg3";178
break;179

180
case "mpeg":181

182
response.ContentType = "video/mpeg";183
break;184

185
case "jpg":186

187
response.ContentType = "image/jpeg";188
break;189

190
case "bmp":191

192
response.ContentType = "image/bmp";193
break;194

195
case "gif":196

197
response.ContentType = "image/gif";198
break;199

200
case "doc":201

202
response.ContentType = "application/msword";203

204
break;205
case "css":206

207
response.ContentType = "text/css";208
break;209

210
default:211

212
response.ContentType = "application/octet-stream";213
break;214

215
}216
217

218
response.WriteFile(file.FullName);219

220
response.End();221
}222

223

224
/// <summary>225
/// 确认字符串是否为空226
/// </summary>227
/// <param name="_value"></param>228
/// <returns></returns>229
private bool Empty(string _value)230
{231
if(_value == null | _value == string.Empty | _value == "")232
{233
return true;234
}235
else236
{237
return false;238
}239
}240

241

242
/// <summary>243
/// 检查是否是非法链接244
/// </summary>245
/// <param name="context"></param>246
/// <param name="_myDomain"></param>247
/// <returns></returns>248
private bool errorLink(HttpContext context,out string _myDomain)249
{250
HttpResponse response = context.Response;251
string myDomain = context.Request.ServerVariables["SERVER_NAME"];252
_myDomain = myDomain ;253
string myDomainIp = context.Request.UserHostAddress;254

255

256
eWebapp_NoLink = ConfigurationSettings.AppSettings["eWebapp_NoLink"];257
eWebapp_AllowLink = ConfigurationSettings.AppSettings["eWebapp_AllowLink"];258

259
try260
{261
eWebapp_AllowOnlyFile = Convert.ToBoolean(ConfigurationSettings.AppSettings["eWebapp_AllowOnlyFile"]);262
}263
catch264
{265
eWebapp_AllowOnlyFile = true;266
}267

268

269
if(context.Request.UrlReferrer != null)270
{271

272
273
//判定referDomain是否存在网站的IP或域名274
string referDomain = context.Request.UrlReferrer.AbsoluteUri.Replace(context.Request.UrlReferrer.AbsolutePath,"");275
string myPath = context.Request.RawUrl;276

277
if(referDomain.IndexOf(myDomainIp) >=0 | referDomain.IndexOf(myDomain)>=0)278
{279
return false;280
}281
else282
{283
//这里使用正则表达对规则进行匹配284
try285
{286
Regex myRegex ;287

288
//检查允许匹配289
if(!Empty(eWebapp_AllowLink))290
{291
292
myRegex = new Regex(eWebapp_AllowLink);293

294
if(myRegex.IsMatch(myPath))295
{296
return false;297
}298

299
}300

301

302
//检查禁止匹配303
if(!Empty(eWebapp_NoLink))304
{305

306
myRegex = new Regex(eWebapp_NoLink);307
if(myRegex.IsMatch(myPath))308
{309
return true;310
}311
else312
{313
return false;314
}315

316
}317

318
return true;319

320
}321
catch322
{323
//如果匹配出错,链接错误324
return true;325
}326
}327
}328
else329
{330
//是否允许直接访问文件331
if(eWebapp_AllowOnlyFile)332
{333
return false;334
}335
else336
{337
return true;338
}339
}340

341
}342
}343
}
