diff Source/Net/HttpReader.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Net/HttpReader.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,465 @@
+/*
+ * File:    HttpReader.cs
+ * Created: 01/17/2003
+ * Author:  Igor Tkachev
+ *          mailto:it@rsdn.ru
+ */
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Security.Cryptography.X509Certificates;
+using System.Collections.Generic;
+
+namespace BLToolkit.Net
+{
+	public delegate void ProcessStream(Stream stream);
+
+	/// <summary>
+	/// Encapsulates WebReader functions.
+	/// </summary>
+	public class HttpReader
+	{
+		#region Costructors
+
+		public HttpReader()
+		{
+			BaseUri = string.Empty;
+		}
+
+		public HttpReader(string baseUri)
+		{
+			BaseUri = baseUri;
+		}
+
+		#endregion
+
+		#region Public Properties
+
+		private X509Certificate _certificate;
+		public  X509Certificate  Certificate
+		{
+			get { return _certificate;  }
+			set { _certificate = value; }
+		}
+
+		private string _baseUri;
+		public  string  BaseUri
+		{
+			get { return _baseUri;  }
+			set { _baseUri = value; }
+		}
+
+		private string _previousUri;
+		public  string  PreviousUri
+		{
+			get { return _previousUri;  }
+			set { _previousUri = value; }
+		}
+
+		private CookieContainer _cookieContainer = new CookieContainer();
+		public  CookieContainer  CookieContainer
+		{
+			get { return _cookieContainer;  }
+			set { _cookieContainer = value; }
+		}
+
+		private string _userAgent = @"HttpReader";
+		public  string  UserAgent
+		{
+			get { return _userAgent;  }
+			set { _userAgent = value; }
+		}
+
+		private string _accept =
+			@"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*";
+		public  string  Accept
+		{
+			get { return _accept;  }
+			set { _accept = value; }
+		}
+
+		private Uri _requestUri;
+		public  Uri  RequestUri
+		{
+			get { return _requestUri;  }
+			set { _requestUri = value; }
+		}
+
+		private string _contentType = string.Empty;
+		public  string  ContentType
+		{
+			get { return _contentType;  }
+			set { _contentType = value; }
+		}
+
+		private IWebProxy _proxy = new WebProxy();
+		public  IWebProxy  Proxy
+		{
+			get { return _proxy;  }
+			set { _proxy = value; }
+		}
+
+		private ICredentials _credentials = CredentialCache.DefaultCredentials;
+		public  ICredentials  Credentials
+		{
+			get { return _credentials;  }
+			set { _credentials = value; }
+		}
+
+		private string _html;
+		public  string  Html
+		{
+			get { return _html; }
+		}
+
+		private readonly Hashtable _headers = new Hashtable();
+		public           Hashtable  Headers
+		{
+			get { return _headers; }
+		}
+
+		private string _location;
+		public  string  Location
+		{
+			get { return _location; }
+		}
+
+		private bool _sendReferer = true;
+		public  bool  SendReferer
+		{
+			get { return _sendReferer;  }
+			set { _sendReferer = value; }
+		}
+
+		private HttpStatusCode _statusCode;
+		public  HttpStatusCode  StatusCode
+		{
+			get { return _statusCode; }
+		}
+
+		private int _timeout;
+		public  int  Timeout
+		{
+			get { return _timeout;  }
+			set { _timeout = value; }
+		}
+
+		#endregion
+
+		#region Public Methods
+
+		public void LoadCertificate(string fileName)
+		{
+			Certificate = X509Certificate.CreateFromCertFile(fileName);
+		}
+
+		#endregion
+
+		#region Request Methods
+
+		private HttpWebRequest PrepareRequest(string method, string requestUri, ProcessStream requestStreamProcessor)
+		{
+			_html = "";
+
+			string uri = BaseUri;
+			
+			if (method != "SOAP")
+				uri += requestUri;
+
+			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
+
+			if (Proxy       != null) request.Proxy       = Proxy;
+			if (Credentials != null) request.Credentials = Credentials;
+
+			request.CookieContainer = CookieContainer;
+			request.UserAgent       = UserAgent;
+			request.Accept          = Accept;
+			request.Method          = method == "SOAP"? "POST" : method;
+			request.KeepAlive       = true;
+
+			if (SendReferer)
+				request.Referer = PreviousUri ?? uri;
+
+			foreach (string key in Headers.Keys)
+				request.Headers.Add(key, Headers[key].ToString());
+
+			if (method == "POST")
+			{
+				request.ContentType       = "application/x-www-form-urlencoded";
+				request.AllowAutoRedirect = false;
+			}
+			else if (method == "SOAP")
+			{
+				request.ContentType       = "text/xml; charset=utf-8";
+				request.AllowAutoRedirect = false;
+
+				request.Headers.Add("SOAPAction", requestUri);
+			}
+			else
+			{
+				request.ContentType       = ContentType;
+				request.AllowAutoRedirect = true;
+			}
+
+			PreviousUri = uri;
+			RequestUri  = request.RequestUri;
+
+			if (Certificate != null)
+				request.ClientCertificates.Add(Certificate);
+
+			if (Timeout != 0)
+				request.Timeout = Timeout;
+
+			if (requestStreamProcessor != null)
+				using (Stream st = request.GetRequestStream())
+					requestStreamProcessor(st);
+
+			return request;
+		}
+
+		public HttpStatusCode Request(
+			string        requestUri,
+			string        method,
+			ProcessStream requestStreamProcessor,
+			ProcessStream responseStreamProcessor)
+		{
+			HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor);
+
+			using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
+			using (Stream          sm   = resp.GetResponseStream())
+			{
+				_statusCode = resp.StatusCode;
+				_location   = resp.Headers["Location"];
+
+				if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false)
+					BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host;
+
+				CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri);
+
+				// This code fixes the situation when a server sets a cookie without the 'path'.
+				// IE takes this as the root ('/') value,
+				// the HttpWebRequest class as the RequestUri.AbsolutePath value.
+				//
+				foreach (Cookie c in cc)
+					if (c.Path == request.RequestUri.AbsolutePath)
+						CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain));
+
+				if (responseStreamProcessor != null)
+					responseStreamProcessor(sm);
+			}
+
+			return StatusCode;
+		}
+
+		public IEnumerable<string> Request(
+			string        requestUri,
+			string        method,
+			ProcessStream requestStreamProcessor)
+		{
+			HttpWebRequest request = PrepareRequest(method, requestUri, requestStreamProcessor);
+
+			using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
+			using (Stream          sm   = resp.GetResponseStream())
+			using (StreamReader    sr   = new StreamReader(sm, Encoding.Default))
+			{
+				_statusCode = resp.StatusCode;
+				_location   = resp.Headers["Location"];
+
+				if (resp.ResponseUri.AbsoluteUri.StartsWith(BaseUri) == false)
+					BaseUri = resp.ResponseUri.Scheme + "://" + resp.ResponseUri.Host;
+
+				CookieCollection cc = request.CookieContainer.GetCookies(request.RequestUri);
+
+				// This code fixes the case when a server sets a cookie without the 'path'.
+				// IE takes this as the root ('/') value,
+				// the HttpWebRequest class as the RequestUri.AbsolutePath value.
+				//
+				foreach (Cookie c in cc)
+					if (c.Path == request.RequestUri.AbsolutePath)
+						CookieContainer.Add(new Cookie(c.Name, c.Value, "/", c.Domain));
+
+				while (true)
+				{
+					string str = sr.ReadLine();
+
+					if (str == null)
+						break;
+
+					yield return str;
+				}
+			}
+		}
+
+		class DefaultRequestStreamProcessor
+		{
+			public DefaultRequestStreamProcessor(string data)
+			{
+				_data = data;
+			}
+
+			readonly string _data;
+
+			public void Process(Stream stream)
+			{
+				byte[] bytes = Encoding.ASCII.GetBytes(_data);
+				stream.Write(bytes, 0, bytes.Length);
+			}
+		}
+
+		class DefaultResponseStreamProcessor
+		{
+			public DefaultResponseStreamProcessor(HttpReader reader)
+			{
+				_reader = reader;
+			}
+
+			readonly HttpReader _reader;
+
+			public void Process(Stream stream)
+			{
+				using (StreamReader sr = new StreamReader(stream, Encoding.Default))
+					_reader._html = sr.ReadToEnd();
+			}
+		}
+
+		public HttpStatusCode Get(string requestUri)
+		{
+			DefaultResponseStreamProcessor rp = new DefaultResponseStreamProcessor(this);
+
+			return Request(requestUri, "GET", null, rp.Process);
+		}
+
+		public HttpStatusCode Get(string requestUri, ProcessStream responseStreamProcessor)
+		{
+			return Request(requestUri, "GET", null, responseStreamProcessor);
+		}
+
+		public HttpStatusCode Post(
+			string requestUri,
+			string postData)
+		{
+			return Post(
+				requestUri,
+				new DefaultRequestStreamProcessor(postData).Process,
+				new DefaultResponseStreamProcessor(this).Process);
+		}
+
+		public HttpStatusCode Post(
+			string        requestUri,
+			ProcessStream requestStreamProcessor)
+		{
+			return Post(
+				requestUri,
+				requestStreamProcessor,
+				new DefaultResponseStreamProcessor(this).Process);
+		}
+
+		public HttpStatusCode Post(
+			string        requestUri,
+			string        postData,
+			ProcessStream responseStreamProcessor)
+		{
+			return Post(
+				requestUri,
+				new ProcessStream(new DefaultRequestStreamProcessor(postData).Process),
+				responseStreamProcessor);
+		}
+
+		public HttpStatusCode Post(
+			string        requestUri,
+			ProcessStream requestStreamProcessor,
+			ProcessStream responseStreamProcessor)
+		{
+			Request(requestUri, "POST", requestStreamProcessor, responseStreamProcessor);
+
+			for (int i = 0; i < 10; i++)
+			{
+				bool post = false;
+
+				switch (StatusCode)
+				{
+					case HttpStatusCode.MultipleChoices:   // 300
+					case HttpStatusCode.MovedPermanently:  // 301
+					case HttpStatusCode.Found:             // 302
+					case HttpStatusCode.SeeOther:          // 303
+						break;
+
+					case HttpStatusCode.TemporaryRedirect: // 307
+						post = true;
+						break;
+
+					default:
+						return StatusCode;
+				}
+
+				if (Location == null)
+					break;
+
+				Uri uri = new Uri(new Uri(PreviousUri), Location);
+
+				BaseUri    = uri.Scheme + "://" + uri.Host;
+				requestUri = uri.AbsolutePath + uri.Query;
+
+				Request(
+					requestUri,
+					post? "POST": "GET",
+					post? requestStreamProcessor: null,
+					responseStreamProcessor);
+			}
+
+			return StatusCode;
+		}
+
+		private HttpStatusCode Soap(
+			string        soapAction,
+			ProcessStream inputStreamProcessor,
+			ProcessStream outputStreamProcessor)
+		{
+			return Request("\"" + soapAction + "\"", "SOAP", inputStreamProcessor, outputStreamProcessor);
+		}
+
+		public HttpStatusCode Soap(string soapAction, string postData)
+		{
+			return Soap(soapAction,
+				new DefaultRequestStreamProcessor(postData).Process,
+				new DefaultResponseStreamProcessor(this).Process);
+		}
+
+		public HttpStatusCode Soap(string soapAction, string postData, ProcessStream outputStreamProcessor)
+		{
+			return Soap(
+				soapAction,
+				new DefaultRequestStreamProcessor(postData).Process,
+				outputStreamProcessor);
+		}
+
+		public IEnumerable<string> SoapEx(string soapAction, string postData)
+		{
+			return Request("\"" + soapAction + "\"", "SOAP", new DefaultRequestStreamProcessor(postData).Process);
+		}
+
+		#endregion
+
+		#region Download
+
+		public void Download(string requestUri, string fileName)
+		{
+			string uri = BaseUri + requestUri;
+
+			WebClient request = new WebClient();
+
+			if (Proxy       != null) request.Proxy       = Proxy;
+			if (Credentials != null) request.Credentials = Credentials;
+
+			foreach (string key in Headers.Keys)
+				request.Headers.Add(key, Headers[key].ToString());
+
+			request.DownloadFile(uri, fileName);
+		}
+
+		#endregion
+	}
+}