1 | using System;
|
---|
2 | using System.Diagnostics;
|
---|
3 | using System.Net;
|
---|
4 | using System.Xml;
|
---|
5 | using System.IO;
|
---|
6 | using System.IO.Compression;
|
---|
7 |
|
---|
8 | namespace SharpVectors.Net
|
---|
9 | {
|
---|
10 | public class ExtendedHttpWebRequestCreator : IWebRequestCreate
|
---|
11 | {
|
---|
12 | public ExtendedHttpWebRequestCreator(){}
|
---|
13 | public WebRequest Create(Uri uri){return new ExtendedHttpWebRequest(uri);}
|
---|
14 | }
|
---|
15 |
|
---|
16 | public class ExtendedHttpWebRequest : WebRequest
|
---|
17 | {
|
---|
18 | #region CacheManager
|
---|
19 | private static ICacheManager cacheManager = new NoCacheManager();
|
---|
20 | public static ICacheManager CacheManager
|
---|
21 | {
|
---|
22 | get{return cacheManager;}
|
---|
23 | set{cacheManager = value;}
|
---|
24 | }
|
---|
25 | #endregion
|
---|
26 |
|
---|
27 | #region Registration
|
---|
28 | public static bool Register()
|
---|
29 | {
|
---|
30 | return WebRequest.RegisterPrefix("http://", new ExtendedHttpWebRequestCreator());
|
---|
31 | }
|
---|
32 | #endregion
|
---|
33 |
|
---|
34 | #region Constructors
|
---|
35 | internal ExtendedHttpWebRequest(Uri uri)
|
---|
36 | {
|
---|
37 | requestUri = uri;
|
---|
38 | }
|
---|
39 | #endregion
|
---|
40 |
|
---|
41 | #region RequestUri
|
---|
42 | private Uri requestUri;
|
---|
43 | public override Uri RequestUri
|
---|
44 | {
|
---|
45 | get
|
---|
46 | {
|
---|
47 | return requestUri;
|
---|
48 | }
|
---|
49 | }
|
---|
50 | #endregion
|
---|
51 |
|
---|
52 | private WebRequest getRequest(CacheInfo cacheInfo)
|
---|
53 | {
|
---|
54 | WebRequest request;
|
---|
55 | if(cacheInfo != null &&
|
---|
56 | cacheInfo.CachedUri != null &&
|
---|
57 | cacheInfo.Expires > DateTime.Now)
|
---|
58 | {
|
---|
59 | request = WebRequest.Create(cacheInfo.CachedUri);
|
---|
60 | }
|
---|
61 | else
|
---|
62 | {
|
---|
63 | request = WebRequest.CreateDefault(RequestUri);
|
---|
64 | }
|
---|
65 |
|
---|
66 | HttpWebRequest hRequest = request as HttpWebRequest;
|
---|
67 | if(hRequest != null && cacheInfo != null && cacheInfo.CachedUri != null)
|
---|
68 | {
|
---|
69 | if(cacheInfo.ETag != null)
|
---|
70 | {
|
---|
71 | hRequest.Headers["If-None-Match"] = cacheInfo.ETag;
|
---|
72 | }
|
---|
73 | if(cacheInfo.LastModified != DateTime.MinValue)
|
---|
74 | {
|
---|
75 | hRequest.IfModifiedSince = cacheInfo.LastModified;
|
---|
76 | }
|
---|
77 |
|
---|
78 | hRequest.Headers["Accept-Encoding"] = "deflate, gzip" ;
|
---|
79 | }
|
---|
80 |
|
---|
81 | return request;
|
---|
82 | }
|
---|
83 |
|
---|
84 | private WebResponse getResponse(WebRequest request, CacheInfo cacheInfo)
|
---|
85 | {
|
---|
86 | WebResponse response = null;
|
---|
87 | try
|
---|
88 | {
|
---|
89 | response = request.GetResponse();
|
---|
90 | }
|
---|
91 | catch(WebException webEx)
|
---|
92 | {
|
---|
93 | HttpWebResponse hresp2 = webEx.Response as HttpWebResponse;
|
---|
94 | if(hresp2 != null)
|
---|
95 | {
|
---|
96 | if(hresp2.StatusCode == HttpStatusCode.NotModified)
|
---|
97 | {
|
---|
98 |
|
---|
99 | if(cacheInfo != null && cacheInfo.CachedUri != null)
|
---|
100 | {
|
---|
101 | request = WebRequest.Create(cacheInfo.CachedUri);
|
---|
102 | }
|
---|
103 | else
|
---|
104 | {
|
---|
105 | request = WebRequest.Create(RequestUri);
|
---|
106 | }
|
---|
107 | response = request.GetResponse();
|
---|
108 | }
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | return response;
|
---|
113 | }
|
---|
114 |
|
---|
115 | private CacheInfo processResponse(WebResponse response)
|
---|
116 | {
|
---|
117 | HttpWebResponse hResponse = response as HttpWebResponse;
|
---|
118 | CacheInfo cacheInfo = null;
|
---|
119 |
|
---|
120 | if(hResponse != null)
|
---|
121 | {
|
---|
122 | DateTime expires;
|
---|
123 | if(hResponse.Headers["Expires"] != null)
|
---|
124 | {
|
---|
125 | expires = DateTime.Parse(hResponse.Headers["Expires"]);
|
---|
126 | }
|
---|
127 | else
|
---|
128 | {
|
---|
129 | expires = DateTime.MinValue;
|
---|
130 | }
|
---|
131 |
|
---|
132 | cacheInfo = new CacheInfo(expires, hResponse.Headers["Etag"], hResponse.LastModified, null, hResponse.ContentType);
|
---|
133 | }
|
---|
134 |
|
---|
135 | return cacheInfo;
|
---|
136 | }
|
---|
137 |
|
---|
138 | private Stream processResponseStream(WebResponse response)
|
---|
139 | {
|
---|
140 | Stream respStream = response.GetResponseStream();
|
---|
141 |
|
---|
142 | string contentEnc = response.Headers["Content-Encoding"];
|
---|
143 | if ( contentEnc != null)
|
---|
144 | {
|
---|
145 | contentEnc = contentEnc.ToLower() ;
|
---|
146 | if ( contentEnc == "gzip" )
|
---|
147 | {
|
---|
148 | respStream = new GZipStream(respStream, CompressionMode.Decompress) ;
|
---|
149 | }
|
---|
150 | else if ( contentEnc == "deflate" )
|
---|
151 | {
|
---|
152 | respStream = new DeflateStream(respStream, CompressionMode.Decompress);
|
---|
153 | }
|
---|
154 | }
|
---|
155 | else if(requestUri.ToString().EndsWith(".svgz"))
|
---|
156 | {
|
---|
157 | // TODO: this is an ugly hack for .svgz files. Fix later!
|
---|
158 | respStream = new GZipStream(respStream, CompressionMode.Decompress);
|
---|
159 | }
|
---|
160 |
|
---|
161 | Stream stream = new MemoryStream();
|
---|
162 | int count = 0;
|
---|
163 | byte[] buffer = new byte[4096];
|
---|
164 | while((count = respStream.Read(buffer, 0, 4096)) > 0) stream.Write(buffer, 0, count);
|
---|
165 |
|
---|
166 | stream.Position = 0;
|
---|
167 |
|
---|
168 | ((IDisposable)respStream).Dispose();
|
---|
169 |
|
---|
170 | return stream;
|
---|
171 | }
|
---|
172 |
|
---|
173 | public override WebResponse GetResponse()
|
---|
174 | {
|
---|
175 | CacheInfo cacheInfo = CacheManager.GetCacheInfo(RequestUri);
|
---|
176 |
|
---|
177 | WebRequest request = getRequest(cacheInfo);
|
---|
178 | WebResponse response = getResponse(request, cacheInfo);
|
---|
179 |
|
---|
180 | Stream stream = processResponseStream(response);
|
---|
181 |
|
---|
182 | if(response is HttpWebResponse)
|
---|
183 | {
|
---|
184 | CacheInfo respCacheInfo = processResponse(response);
|
---|
185 |
|
---|
186 | CacheManager.SetCacheInfo(RequestUri, respCacheInfo, stream);
|
---|
187 | }
|
---|
188 |
|
---|
189 | return new ExtendedHttpWebResponse(RequestUri, response, stream, cacheInfo);
|
---|
190 | }
|
---|
191 | }
|
---|
192 | }
|
---|