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