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 }