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
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.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


2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36



37


38

39

40

41

42

43



44

45



46

47

48

49

50

51

52

53

54

55

56

57

58

59



60

61

62

63

64

65

66

67

68



69

70

71

72

73

74

75



76

77

78

79

80



81

82

83

84

85

86

87



88

89

90



91

92

93

94

95

96


97

98

99

100

101

102



103

104

105

106

107

108



109

110

111



112

113

114

115

116

117



118

119

120

121



122

123

124



125

126

127

128

129



130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151


152

153

154

155

156

157



158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174



175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224


225

226

227

228

229

230



231

232



233

234

235

236



237

238

239

240

241

242


243

244

245

246

247

248

249



250

251

252

253

254

255

256

257

258

259

260



261

262

263

264



265

266

267

268

269

270



271

272

273

274

275

276

277

278



279

280

281

282



283

284

285



286

287

288

289

290



291

292

293

294

295



296

297

298

299

300

301

302

303

304



305

306

307

308



309

310

311

312



313

314

315

316

317

318

319

320

321

322



323

324

325

326

327

328

329



330

331

332



333

334

335

336



337

338

339

340

341

342

343

344
