/
ProxyCache.cs
112 lines (97 loc) · 3.83 KB
/
ProxyCache.cs
1
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Net;
using System.Threading;
namespace HTTPProxyServer
{
public static class ProxyCache
{
private static Hashtable _cache = new Hashtable();
private static Object _cacheLockObj = new object();
private static Object _statsLockObj = new object();
private static Int32 _hits;
public static CacheEntry GetData(HttpWebRequest request)
{
CacheKey key = new CacheKey(request.RequestUri.AbsoluteUri, request.UserAgent);
if (_cache[key] != null)
{
CacheEntry entry = (CacheEntry)_cache[key];
if (entry.FlagRemove || (entry.Expires.HasValue && entry.Expires < DateTime.Now))
{
//don't remove it here, just flag
entry.FlagRemove = true;
return null;
}
Monitor.Enter(_statsLockObj);
_hits++;
Monitor.Exit(_statsLockObj);
return entry;
}
return null;
}
public static CacheEntry MakeEntry(HttpWebRequest request, HttpWebResponse response,List<Tuple<String,String>> headers, DateTime? expires)
{
CacheEntry newEntry = new CacheEntry();
newEntry.Expires = expires;
newEntry.DateStored = DateTime.Now;
newEntry.Headers = headers;
newEntry.Key = new CacheKey(request.RequestUri.AbsoluteUri, request.UserAgent);
newEntry.StatusCode = response.StatusCode;
newEntry.StatusDescription = response.StatusDescription;
if (response.ContentLength > 0)
newEntry.ResponseBytes = new Byte[response.ContentLength];
return newEntry;
}
public static void AddData(CacheEntry entry)
{
Monitor.Enter(_cacheLockObj);
if (!_cache.Contains(entry.Key))
_cache.Add(entry.Key, entry);
Monitor.Exit(_cacheLockObj);
}
public static Boolean CanCache(WebHeaderCollection headers, ref DateTime? expires)
{
foreach (String s in headers.AllKeys)
{
String value = headers[s].ToLower();
switch (s.ToLower())
{
case "cache-control":
if (value.Contains("max-age"))
{
int seconds;
if (int.TryParse(value, out seconds))
{
if (seconds == 0)
return false;
DateTime d = DateTime.Now.AddSeconds(seconds);
if (!expires.HasValue || expires.Value < d)
expires = d;
}
}
if (value.Contains("private") || value.Contains("no-cache"))
return false;
else if (value.Contains("public") || value.Contains("no-store"))
return true;
break;
case "pragma":
if (value == "no-cache")
return false;
break;
case "expires":
DateTime dExpire;
if (DateTime.TryParse(value, out dExpire))
{
if (!expires.HasValue || expires.Value < dExpire)
expires = dExpire;
}
break;
}
}
return true;
}
}
}