Mercurial > pub > bltoolkit
comparison Source/Net/HttpReader.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 /* | |
2 * File: HttpReader.cs | |
3 * Created: 01/17/2003 | |
4 * Author: Igor Tkachev | |
5 * mailto:it@rsdn.ru | |
6 */ | |
7 | |
8 using System; | |
9 using System.Collections; | |
10 using System.IO; | |
11 using System.Net; | |
12 using System.Text; | |
13 using System.Security.Cryptography.X509Certificates; | |
14 using System.Collections.Generic; | |
15 | |
16 namespace BLToolkit.Net | |
17 { | |
18 public delegate void ProcessStream(Stream stream); | |
19 | |
20 /// <summary> | |
21 /// Encapsulates WebReader functions. | |
22 /// </summary> | |
23 public class HttpReader | |
24 { | |
25 #region Costructors | |
26 | |
27 public HttpReader() | |
28 { | |
29 BaseUri = string.Empty; | |
30 } | |
31 | |
32 public HttpReader(string baseUri) | |
33 { | |
34 BaseUri = baseUri; | |
35 } | |
36 | |
37 #endregion | |
38 | |
39 #region Public Properties | |
40 | |
41 private X509Certificate _certificate; | |
42 public X509Certificate Certificate | |
43 { | |
44 get { return _certificate; } | |
45 set { _certificate = value; } | |
46 } | |
47 | |
48 private string _baseUri; | |
49 public string BaseUri | |
50 { | |
51 get { return _baseUri; } | |
52 set { _baseUri = value; } | |
53 } | |
54 | |
55 private string _previousUri; | |
56 public string PreviousUri | |
57 { | |
58 get { return _previousUri; } | |
59 set { _previousUri = value; } | |
60 } | |
61 | |
62 private CookieContainer _cookieContainer = new CookieContainer(); | |
63 public CookieContainer CookieContainer | |
64 { | |
65 get { return _cookieContainer; } | |
66 set { _cookieContainer = value; } | |
67 } | |
68 | |
69 private string _userAgent = @"HttpReader"; | |
70 public string UserAgent | |
71 { | |
72 get { return _userAgent; } | |
73 set { _userAgent = value; } | |
74 } | |
75 | |
76 private string _accept = | |
77 @"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*"; | |
78 public string Accept | |
79 { | |
80 get { return _accept; } | |
81 set { _accept = value; } | |
82 } | |
83 | |
84 private Uri _requestUri; | |
85 public Uri RequestUri | |
86 { | |
87 get { return _requestUri; } | |
88 set { _requestUri = value; } | |
89 } | |
90 | |
91 private string _contentType = string.Empty; | |
92 public string ContentType | |
93 { | |
94 get { return _contentType; } | |
95 set { _contentType = value; } | |
96 } | |
97 | |
98 private IWebProxy _proxy = new WebProxy(); | |
99 public IWebProxy Proxy | |
100 { | |
101 get { return _proxy; } | |
102 set { _proxy = value; } | |
103 } | |
104 | |
105 private ICredentials _credentials = CredentialCache.DefaultCredentials; | |
106 public ICredentials Credentials | |
107 { | |
108 get { return _credentials; } | |
109 set { _credentials = value; } | |
110 } | |
111 | |
112 private string _html; | |
113 public string Html | |
114 { | |
115 get { return _html; } | |
116 } | |
117 | |
118 private readonly Hashtable _headers = new Hashtable(); | |
119 public Hashtable Headers | |
120 { | |
121 get { return _headers; } | |
122 } | |
123 | |
124 private string _location; | |
125 public string Location | |
126 { | |
127 get { return _location; } | |
128 } | |
129 | |
130 private bool _sendReferer = true; | |
131 public bool SendReferer | |
132 { | |
133 get { return _sendReferer; } | |
134 set { _sendReferer = value; } | |
135 } | |
136 | |
137 private HttpStatusCode _statusCode; | |
138 public HttpStatusCode StatusCode | |
139 { | |
140 get { return _statusCode; } | |
141 } | |
142 | |
143 private int _timeout; | |
144 public int Timeout | |
145 { | |
146 get { return _timeout; } | |
147 set { _timeout = value; } | |
148 } | |
149 | |
150 #endregion | |
151 | |
152 #region Public Methods | |
153 | |
154 public void LoadCertificate(string fileName) | |
155 { | |
156 Certificate = X509Certificate.CreateFromCertFile(fileName); | |
157 } | |
158 | |
159 #endregion | |
160 | |
161 #region Request Methods | |
162 | |
163 private HttpWebRequest PrepareRequest(string method, string requestUri, ProcessStream requestStreamProcessor) | |
164 { | |
165 _html = ""; | |
166 | |
167 string uri = BaseUri; | |
168 | |
169 if (method != "SOAP") | |
170 uri += requestUri; | |
171 | |
172 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); | |
173 | |
174 if (Proxy != null) request.Proxy = Proxy; | |
175 if (Credentials != null) request.Credentials = Credentials; | |
176 | |
177 request.CookieContainer = CookieContainer; | |
178 request.UserAgent = UserAgent; | |
179 request.Accept = Accept; | |
180 request.Method = method == "SOAP"? "POST" : method; | |
181 request.KeepAlive = true; | |
182 | |
183 if (SendReferer) | |
184 request.Referer = PreviousUri ?? uri; | |
185 | |
186 foreach (string key in Headers.Keys) | |
187 request.Headers.Add(key, Headers[key].ToString()); | |
188 | |
189 if (method == "POST") | |
190 { | |
191 request.ContentType = "application/x-www-form-urlencoded"; | |
192 request.AllowAutoRedirect = false; | |
193 } | |
194 else if (method == "SOAP") | |
195 { | |
196 request.ContentType = "text/xml; charset=utf-8"; | |
197 request.AllowAutoRedirect = false; | |
198 | |
199 request.Headers.Add("SOAPAction", requestUri); | |
200 } | |
201 else | |
202 { | |
203 request.ContentType = ContentType; | |
204 request.AllowAutoRedirect = true; | |
205 } | |
206 | |
207 PreviousUri = uri; | |
208 RequestUri = request.RequestUri; | |
209 | |
210 if (Certificate != null) | |
211 request.ClientCertificates.Add(Certificate); | |
212 | |
213 if (Timeout != 0) | |
214 request.Timeout = Timeout; | |
215 | |
216 if (requestStreamProcessor != null) | |
217 using (Stream st = request.GetRequestStream()) | |
218 requestStreamProcessor(st); | |
219 | |
220 return request; | |
221 } | |
222 | |
223 public HttpStatusCode Request( | |
224 string requestUri, | |
225 string method, | |
226 ProcessStream requestStreamProcessor, | |
227 ProcessStream responseStreamProcessor) | |
228 { | |
229 HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor); | |
230 | |
231 using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) | |
232 using (Stream sm = resp.GetResponseStream()) | |
233 { | |
234 _statusCode = resp.StatusCode; | |
235 _location = resp.Headers["Location"]; | |
236 | |
237 if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false) | |
238 BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host; | |
239 | |
240 CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri); | |
241 | |
242 // This code fixes the situation when a server sets a cookie without the 'path'. | |
243 // IE takes this as the root ('/') value, | |
244 // the HttpWebRequest class as the RequestUri.AbsolutePath value. | |
245 // | |
246 foreach (Cookie c in cc) | |
247 if (c.Path == request.RequestUri.AbsolutePath) | |
248 CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain)); | |
249 | |
250 if (responseStreamProcessor != null) | |
251 responseStreamProcessor(sm); | |
252 } | |
253 | |
254 return StatusCode; | |
255 } | |
256 | |
257 public IEnumerable<string> Request( | |
258 string requestUri, | |
259 string method, | |
260 ProcessStream requestStreamProcessor) | |
261 { | |
262 HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor); | |
263 | |
264 using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) | |
265 using (Stream sm = resp.GetResponseStream()) | |
266 using (StreamReader sr = new StreamReader(sm, Encoding.Default)) | |
267 { | |
268 _statusCode = resp.StatusCode; | |
269 _location = resp.Headers["Location"]; | |
270 | |
271 if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false) | |
272 BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host; | |
273 | |
274 CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri); | |
275 | |
276 // This code fixes the case when a server sets a cookie without the 'path'. | |
277 // IE takes this as the root ('/') value, | |
278 // the HttpWebRequest class as the RequestUri.AbsolutePath value. | |
279 // | |
280 foreach (Cookie c in cc) | |
281 if (c.Path == request.RequestUri.AbsolutePath) | |
282 CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain)); | |
283 | |
284 while (true) | |
285 { | |
286 string str = sr.ReadLine(); | |
287 | |
288 if (str == null) | |
289 break; | |
290 | |
291 yield return str; | |
292 } | |
293 } | |
294 } | |
295 | |
296 class DefaultRequestStreamProcessor | |
297 { | |
298 public DefaultRequestStreamProcessor(string data) | |
299 { | |
300 _data = data; | |
301 } | |
302 | |
303 readonly string _data; | |
304 | |
305 public void Process(Stream stream) | |
306 { | |
307 byte[] bytes = Encoding.ASCII.GetBytes(_data); | |
308 stream.Write(bytes, 0, bytes.Length); | |
309 } | |
310 } | |
311 | |
312 class DefaultResponseStreamProcessor | |
313 { | |
314 public DefaultResponseStreamProcessor(HttpReader reader) | |
315 { | |
316 _reader = reader; | |
317 } | |
318 | |
319 readonly HttpReader _reader; | |
320 | |
321 public void Process(Stream stream) | |
322 { | |
323 using (StreamReader sr = new StreamReader(stream, Encoding.Default)) | |
324 _reader._html = sr.ReadToEnd(); | |
325 } | |
326 } | |
327 | |
328 public HttpStatusCode Get(string requestUri) | |
329 { | |
330 DefaultResponseStreamProcessor rp = new DefaultResponseStreamProcessor(this); | |
331 | |
332 return Request(requestUri, "GET", null, rp.Process); | |
333 } | |
334 | |
335 public HttpStatusCode Get(string requestUri, ProcessStream responseStreamProcessor) | |
336 { | |
337 return Request(requestUri, "GET", null, responseStreamProcessor); | |
338 } | |
339 | |
340 public HttpStatusCode Post( | |
341 string requestUri, | |
342 string postData) | |
343 { | |
344 return Post( | |
345 requestUri, | |
346 new DefaultRequestStreamProcessor(postData).Process, | |
347 new DefaultResponseStreamProcessor(this).Process); | |
348 } | |
349 | |
350 public HttpStatusCode Post( | |
351 string requestUri, | |
352 ProcessStream requestStreamProcessor) | |
353 { | |
354 return Post( | |
355 requestUri, | |
356 requestStreamProcessor, | |
357 new DefaultResponseStreamProcessor(this).Process); | |
358 } | |
359 | |
360 public HttpStatusCode Post( | |
361 string requestUri, | |
362 string postData, | |
363 ProcessStream responseStreamProcessor) | |
364 { | |
365 return Post( | |
366 requestUri, | |
367 new ProcessStream(new DefaultRequestStreamProcessor(postData).Process), | |
368 responseStreamProcessor); | |
369 } | |
370 | |
371 public HttpStatusCode Post( | |
372 string requestUri, | |
373 ProcessStream requestStreamProcessor, | |
374 ProcessStream responseStreamProcessor) | |
375 { | |
376 Request(requestUri, "POST", requestStreamProcessor, responseStreamProcessor); | |
377 | |
378 for (int i = 0; i < 10; i++) | |
379 { | |
380 bool post = false; | |
381 | |
382 switch (StatusCode) | |
383 { | |
384 case HttpStatusCode.MultipleChoices: // 300 | |
385 case HttpStatusCode.MovedPermanently: // 301 | |
386 case HttpStatusCode.Found: // 302 | |
387 case HttpStatusCode.SeeOther: // 303 | |
388 break; | |
389 | |
390 case HttpStatusCode.TemporaryRedirect: // 307 | |
391 post = true; | |
392 break; | |
393 | |
394 default: | |
395 return StatusCode; | |
396 } | |
397 | |
398 if (Location == null) | |
399 break; | |
400 | |
401 Uri uri = new Uri(new Uri(PreviousUri), Location); | |
402 | |
403 BaseUri = uri.Scheme + "://" + uri.Host; | |
404 requestUri = uri.AbsolutePath + uri.Query; | |
405 | |
406 Request( | |
407 requestUri, | |
408 post? "POST": "GET", | |
409 post? requestStreamProcessor: null, | |
410 responseStreamProcessor); | |
411 } | |
412 | |
413 return StatusCode; | |
414 } | |
415 | |
416 private HttpStatusCode Soap( | |
417 string soapAction, | |
418 ProcessStream inputStreamProcessor, | |
419 ProcessStream outputStreamProcessor) | |
420 { | |
421 return Request("\"" + soapAction + "\"", "SOAP", inputStreamProcessor, outputStreamProcessor); | |
422 } | |
423 | |
424 public HttpStatusCode Soap(string soapAction, string postData) | |
425 { | |
426 return Soap(soapAction, | |
427 new DefaultRequestStreamProcessor(postData).Process, | |
428 new DefaultResponseStreamProcessor(this).Process); | |
429 } | |
430 | |
431 public HttpStatusCode Soap(string soapAction, string postData, ProcessStream outputStreamProcessor) | |
432 { | |
433 return Soap( | |
434 soapAction, | |
435 new DefaultRequestStreamProcessor(postData).Process, | |
436 outputStreamProcessor); | |
437 } | |
438 | |
439 public IEnumerable<string> SoapEx(string soapAction, string postData) | |
440 { | |
441 return Request("\"" + soapAction + "\"", "SOAP", new DefaultRequestStreamProcessor(postData).Process); | |
442 } | |
443 | |
444 #endregion | |
445 | |
446 #region Download | |
447 | |
448 public void Download(string requestUri, string fileName) | |
449 { | |
450 string uri = BaseUri + requestUri; | |
451 | |
452 WebClient request = new WebClient(); | |
453 | |
454 if (Proxy != null) request.Proxy = Proxy; | |
455 if (Credentials != null) request.Credentials = Credentials; | |
456 | |
457 foreach (string key in Headers.Keys) | |
458 request.Headers.Add(key, Headers[key].ToString()); | |
459 | |
460 request.DownloadFile(uri, fileName); | |
461 } | |
462 | |
463 #endregion | |
464 } | |
465 } |