(转)防盗链

 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}

344
原文地址:https://www.cnblogs.com/zwei1121/p/596827.html