using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO.Compression;
using System.Net.Cache;
namespace HttpProc
{
///
/// 上傳數(shù)據(jù)參數(shù)
///
public class UploadEventArgs : EventArgs
{
int bytesSent;
int totalBytes;
///
/// 已發(fā)送的字節(jié)數(shù)
///
public int BytesSent
{
get { return bytesSent; }
set { bytesSent = value; }
}
///
/// 總字節(jié)數(shù)
///
public int TotalBytes
{
get { return totalBytes; }
set { totalBytes = value; }
}
}
///
/// 下載數(shù)據(jù)參數(shù)
///
public class DownloadEventArgs : EventArgs
{
int bytesReceived;
int totalBytes;
byte[] receivedData;
///
/// 已接收的字節(jié)數(shù)
///
public int BytesReceived
{
get { return bytesReceived; }
set { bytesReceived = value; }
}
///
/// 總字節(jié)數(shù)
///
public int TotalBytes
{
get { return totalBytes; }
set { totalBytes = value; }
}
///
/// 當(dāng)前緩沖區(qū)接收的數(shù)據(jù)
///
public byte[] ReceivedData
{
get { return receivedData; }
set { receivedData = value; }
}
}
public class WebClient
{
Encoding encoding = Encoding.Default;
string respHtml = "";
WebProxy proxy;
static CookieContainer cc;
WebHeaderCollection requestHeaders;
WebHeaderCollection responseHeaders;
int bufferSize = 15240;
public event EventHandler
public event EventHandler
static WebClient()
{
LoadCookiesFromDisk();
}
///
/// 創(chuàng)建WebClient的實例
///
public WebClient()
{
requestHeaders = new WebHeaderCollection();
responseHeaders = new WebHeaderCollection();
}
///
/// 設(shè)置發(fā)送和接收的數(shù)據(jù)緩沖大小
///
public int BufferSize
{
get { return bufferSize; }
set { bufferSize = value; }
}
///
/// 獲取響應(yīng)頭集合
///
public WebHeaderCollection ResponseHeaders
{
get { return responseHeaders; }
}
///
/// 獲取請求頭集合
///
public WebHeaderCollection RequestHeaders
{
get { return requestHeaders; }
}
///
/// 獲取或設(shè)置代理
///
public WebProxy Proxy
{
get { return proxy; }
set { proxy = value; }
}
///
/// 獲取或設(shè)置請求與響應(yīng)的文本編碼方式
///
public Encoding Encoding
{
get { return encoding; }
set { encoding = value; }
}
///
/// 獲取或設(shè)置響應(yīng)的html代碼
///
public string RespHtml
{
get { return respHtml; }
set { respHtml = value; }
}
///
/// 獲取或設(shè)置與請求關(guān)聯(lián)的Cookie容器
///
public CookieContainer CookieContainer
{
get { return cc; }
set { cc = value; }
}
///
/// 獲取網(wǎng)頁源代碼
///
///網(wǎng)址
///
public string GetHtml(string url)
{
HttpWebRequest request = CreateRequest(url, "GET");
respHtml = encoding.GetString(GetData(request));
return respHtml;
}
///
/// 下載文件
///
///文件URL地址
///文件保存完整路徑
public void DownloadFile(string url, string filename)
{
FileStream fs = null;
try
{
HttpWebRequest request = CreateRequest(url, "GET");
byte[] data = GetData(request);
fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
fs.Write(data, 0, data.Length);
}
finally
{
if (fs != null) fs.Close();
}
}
///
/// 從指定URL下載數(shù)據(jù)
///
///網(wǎng)址
///
public byte[] GetData(string url)
{
HttpWebRequest request = CreateRequest(url, "GET");
return GetData(request);
}
///
/// 向指定URL發(fā)送文本數(shù)據(jù)
///
///網(wǎng)址
///urlencode編碼的文本數(shù)據(jù)
///
public string Post(string url, string postData)
{
byte[] data = encoding.GetBytes(postData);
return Post(url, data);
}
///
/// 向指定URL發(fā)送字節(jié)數(shù)據(jù)
///
///網(wǎng)址
///發(fā)送的字節(jié)數(shù)組
///
public string Post(string url, byte[] postData)
{
HttpWebRequest request = CreateRequest(url, "POST");
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
request.KeepAlive = true;
PostData(request, postData);
respHtml = encoding.GetString(GetData(request));
return respHtml;
}
///
/// 向指定網(wǎng)址發(fā)送mulitpart編碼的數(shù)據(jù)
///
///網(wǎng)址
///mulitpart form data
///
public string Post(string url, MultipartForm mulitpartForm)
{
HttpWebRequest request = CreateRequest(url, "POST");
request.ContentType = mulitpartForm.ContentType;
request.ContentLength = mulitpartForm.FormData.Length;
request.KeepAlive = true;
PostData(request, mulitpartForm.FormData);
respHtml = encoding.GetString(GetData(request));
return respHtml;
}
///
/// 讀取請求返回的數(shù)據(jù)
///
///請求對象
///
private byte[] GetData(HttpWebRequest request)
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
responseHeaders = response.Headers;
SaveCookiesToDisk();
DownloadEventArgs args = new DownloadEventArgs();
if (responseHeaders[HttpResponseHeader.ContentLength] != null)
args.TotalBytes = Convert.ToInt32(responseHeaders[HttpResponseHeader.ContentLength]);
MemoryStream ms = new MemoryStream();
int count = 0;
byte[] buf = new byte[bufferSize];
while ((count = stream.Read(buf, 0, buf.Length)) > 0)
{
ms.Write(buf, 0, count);
if (this.DownloadProgressChanged != null)
{
args.BytesReceived += count;
args.ReceivedData = new byte[count];
Array.Copy(buf, args.ReceivedData, count);
this.DownloadProgressChanged(this, args);
}
}
stream.Close();
//解壓
if (ResponseHeaders[HttpResponseHeader.ContentEncoding] != null)
{
MemoryStream msTemp = new MemoryStream();
count = 0;
buf = new byte[100];
switch (ResponseHeaders[HttpResponseHeader.ContentEncoding].ToLower())
{
case "gzip":
GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
while ((count = gzip.Read(buf, 0, buf.Length)) > 0)
{
msTemp.Write(buf, 0, count);
}
return msTemp.ToArray();
case "deflate":
DeflateStream deflate = new DeflateStream(ms, CompressionMode.Decompress);
while ((count = deflate.Read(buf, 0, buf.Length)) > 0)
{
msTemp.Write(buf, 0, count);
}
return msTemp.ToArray();
default:
break;
}
}
return ms.ToArray();
}
///
/// 發(fā)送請求數(shù)據(jù)
///
///請求對象
///請求發(fā)送的字節(jié)數(shù)組
private void PostData(HttpWebRequest request, byte[] postData)
{
int offset = 0;
int sendBufferSize = bufferSize;
int remainBytes = 0;
Stream stream = request.GetRequestStream();
UploadEventArgs args = new UploadEventArgs();
args.TotalBytes = postData.Length;
while ((remainBytes = postData.Length - offset) > 0)
{
if (sendBufferSize > remainBytes) sendBufferSize = remainBytes;
stream.Write(postData, offset, sendBufferSize);
offset += sendBufferSize;
if (this.UploadProgressChanged != null)
{
args.BytesSent = offset;
this.UploadProgressChanged(this, args);
}
}
stream.Close();
}
///
/// 創(chuàng)建HTTP請求
///
///URL地址
///
private HttpWebRequest CreateRequest(string url, string method)
{
Uri uri = new Uri(url);
if (uri.Scheme == "https")
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(this.CheckValidationResult);
// Set a default policy level for the "http:" and "https" schemes.
HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Revalidate);
HttpWebRequest.DefaultCachePolicy = policy;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AllowAutoRedirect = false;
request.AllowWriteStreamBuffering = false;
request.Method = method;
if (proxy != null) request.Proxy = proxy;
request.CookieContainer = cc;
foreach (string key in requestHeaders.Keys)
{
request.Headers.Add(key, requestHeaders[key]);
}
requestHeaders.Clear();
return request;
}
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
///
/// 將Cookie保存到磁盤
///
private static void SaveCookiesToDisk()
{
string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "\\webclient.cookie";
FileStream fs = null;
try
{
fs = new FileStream(cookieFile, FileMode.Create);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
formater.Serialize(fs, cc);
}
finally
{
if (fs != null) fs.Close();
}
}
///
/// 從磁盤加載Cookie
///
private static void LoadCookiesFromDisk()
{
cc = new CookieContainer();
string cookieFile = System.Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "\\webclient.cookie";
if (!File.Exists(cookieFile))
return;
FileStream fs = null;
try
{
fs = new FileStream(cookieFile, FileMode.Open, FileAccess.Read, FileShare.Read);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
cc = (CookieContainer)formater.Deserialize(fs);
}
finally
{
if (fs != null) fs.Close();
}
}
}
///
/// 對文件和文本數(shù)據(jù)進行Multipart形式的編碼
///
public class MultipartForm
{
private Encoding encoding;
private MemoryStream ms;
private string boundary;
private byte[] formData;
///
/// 獲取編碼后的字節(jié)數(shù)組
///
public byte[] FormData
{
get
{
if (formData == null)
{
byte[] buffer = encoding.GetBytes("--" + this.boundary + "--\r\n");
ms.Write(buffer, 0, buffer.Length);
formData = ms.ToArray();
}
return formData;
}
}
///
/// 獲取此編碼內(nèi)容的類型
///
public string ContentType
{
get { return string.Format("multipart/form-data; boundary={0}", this.boundary); }
}
///
/// 獲取或設(shè)置對字符串采用的編碼類型
///
public Encoding StringEncoding
{
set { encoding = value; }
get { return encoding; }
}
///
/// 實例化
///
public MultipartForm()
{
boundary = string.Format("--{0}--", Guid.NewGuid());
ms = new MemoryStream();
encoding = Encoding.Default;
}
///
/// 添加一個文件
///
///文件域名稱
///文件的完整路徑
public void AddFlie(string name, string filename)
{
if (!File.Exists(filename))
throw new FileNotFoundException("嘗試添加不存在的文件。", filename);
FileStream fs = null;
byte[] fileData ={ };
try
{
fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
fileData = new byte[fs.Length];
fs.Read(fileData, 0, fileData.Length);
this.AddFlie(name, Path.GetFileName(filename), fileData, fileData.Length);
}
catch (Exception)
{
throw;
}
finally
{
if (fs != null) fs.Close();
}
}
///
/// 添加一個文件
///
///文件域名稱
///文件名
///文件二進制數(shù)據(jù)
///二進制數(shù)據(jù)大小
public void AddFlie(string name, string filename, byte[] fileData, int dataLength)
{
if (dataLength <= 0 || dataLength > fileData.Length)
{
dataLength = fileData.Length;
}
StringBuilder sb = new StringBuilder();
sb.AppendFormat("--{0}\r\n", this.boundary);
sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\n", name, filename);
sb.AppendFormat("Content-Type: {0}\r\n", this.GetContentType(filename));
sb.Append("\r\n");
byte[] buf = encoding.GetBytes(sb.ToString());
ms.Write(buf, 0, buf.Length);
ms.Write(fileData, 0, dataLength);
byte[] crlf = encoding.GetBytes("\r\n");
ms.Write(crlf, 0, crlf.Length);
}
///
/// 添加字符串
///
///文本域名稱
///文本值
public void AddString(string name, string value)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("--{0}\r\n", this.boundary);
sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"\r\n", name);
sb.Append("\r\n");
sb.AppendFormat("{0}\r\n", value);
byte[] buf = encoding.GetBytes(sb.ToString());
ms.Write(buf, 0, buf.Length);
}
///
/// 從注冊表獲取文件類型
///
///包含擴展名的文件名
///
private string GetContentType(string filename)
{
Microsoft.Win32.RegistryKey fileExtKey = null; ;
string contentType = "application/stream";
try
{
fileExtKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filename));
contentType = fileExtKey.GetValue("Content Type", contentType).ToString();
}
finally
{
if (fileExtKey != null) fileExtKey.Close();
}
return contentType;
}
}
}
使用實例:
class Test
{
public static void Test1()
{
HttpProc.WebClient c = new HttpProc.WebClient();
c.DownloadProgressChanged += new EventHandler
c.UploadProgressChanged += new EventHandler
//登錄百度空間
c.Post("https://passport.baidu.com/?login", "username=hddo&password=**********");
if (c.RespHtml.Contains("passport.baidu.com"))
{
//登錄成功
}
//向百度相冊上傳圖片
HttpProc.MultipartForm mf = new HttpProc.MultipartForm();
mf.AddString("BrowserType", "1");
mf.AddString("spPhotoText0", "10086");
mf.AddString("spAlbumName", "默認相冊");
mf.AddString("spMaxSize", "1600");
mf.AddString("spQuality", "90");
mf.AddFlie("file1", "D:\\Blue hills2.jpg");
c.Post("http://hiup.baidu.com/hddo/upload", mf);
if (c.RespHtml.Contains("submit(0,0)"))
{
//上傳圖片成功
}
}
static void c_UploadProgressChanged(object sender, HttpProc.UploadEventArgs e)
{
//顯示上傳進度
}
static void c_DownloadProgressChanged(object sender, HttpProc.DownloadEventArgs e)
{
//顯示下載進度
}
}