1/*
2 *
3 * 防盗链IHttpHandler
4 *
5 *
6 * 增加了对文件关键字的选择(即仅对文件名存在某些关键字或不存在某些关键字进行过滤)
7 * 设置web.config中<appSettings>节以下值
8 * string eWebapp_NoLink 如果文件名符合该正确表态式将进行过滤(不设置对所有进行过滤)
9 * string eWebapp_AllowLink 如果文件名符合该正确表态式将不进行过滤(优先权高于AllowLink,不设置则服从AllowLink)
10 * booleWebapp_ AllowOnlyFile 如果为False,(默认true)则不允许用户直接对该文件进行访问建议为true
11 *
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.com
22 * eWebapp.cnblogs.com
23 *
24 */
25
26
27using System;
28using System.Web;
29using System.Drawing;
30using System.Drawing.Imaging;
31using System.IO;
32using System.Configuration;
33using System.Text.RegularExpressions;
34
35namespace eWebapp.NoLink
36{
37 /// <summary>
38 /// 防盗链IHttpHandler
39 ///
40 /// 垃圾猪 2005-9-12 修正
41 /// </summary>
42 public class IHandler : IHttpHandler
43 {
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 else
80 {
81 Real(context.Response,context.Request);
82 }
83
84 }
85
86 public bool IsReusable
87 {
88 get
89
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 try
108 {
109 int _myErrorWidth = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Width"]);
110 if(_myErrorWidth > 0 )
111 {
112 myErrorWidth = _myErrorWidth;
113 }
114
115 }
116 catch
117 {
118
119 }
120 try
121 {
122 int _myErrorHeight = Convert.ToInt32(ConfigurationSettings.AppSettings["eWebapp_Error_Height"]);
123 if(_myErrorHeight > 0 )
124 {
125 myErrorHeight = _myErrorHeight;
126 }
127 }
128 catch
129 {
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 else
236 {
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 try
260 {
261 eWebapp_AllowOnlyFile = Convert.ToBoolean(ConfigurationSettings.AppSettings["eWebapp_AllowOnlyFile"]);
262 }
263 catch
264 {
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 else
282 {
283 //这里使用正则表达对规则进行匹配
284 try
285 {
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 else
312 {
313 return false;
314 }
315
316 }
317
318 return true;
319
320 }
321 catch
322 {
323 //如果匹配出错,链接错误
324 return true;
325 }
326 }
327 }
328 else
329 {
330 //是否允许直接访问文件
331 if(eWebapp_AllowOnlyFile)
332 {
333 return false;
334 }
335 else
336 {
337 return true;
338 }
339 }
340
341 }
342 }
343}