博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Discuz!NT3.0 API跨域登陆------无需使用论坛的登陆页面

Posted on 2011-01-03 14:39  dora兔子  阅读(2751)  评论(1)    收藏  举报

首先想说的是,discuznt的api实在是太蛋疼了,无与伦比的蛋疼。

 下面是正题,discuz!NT的api是用登陆后返回的auto_token来识别用户是否登录的,

所以要绕开论坛登录页面,就必须模拟用户的提交动作。

方法也就自然是模拟post和get方式的提交。

由于discuz十分蛋疼,

原来的的登陆流程是,检查用户是否登录——>跳转论坛登录页面——>post提交UserName,Password获得auto_token并写用户cookie

        ——>获得auto_token使用api获取用户信息得到游客身份——>再次跳会论坛登录页面get提交用户cookie,再次获得相同的auto_Token

        ——>通过再次获得的auto_Token使用api获取用户完整的userInfo(有时会失败,失败的话重复get提交即可)

 是不是很疼啊。。

所以我的实现流程是,检查用户是否登录——>跳转本站自己的登录页面——>post提交用户信息到本站服务器

        ——>在服务器端将用户信息构造成原站的post请求发送出去,接收response并将获得的cookie写进另外构造的get请求中发送给原站,获得返回的auto_token

        ——>调回本站主页,并将autoToken作为参数传给主页,主页通过api获取userInfo(有时也会失败,使用是否post过的标志session,在再次调回登录页面的pageload事件中再次进行get请求)

一下是登录时的核心代码,需要另外实现httpproc,此代码网上可搜到。    
代码
 1             string remoteLoginUrl = string.Format("{0}login.aspx?api_key={1}", url, api_key);
 2             //建立请求客户端
 3             WebClient client = new WebClient();
 4             client.Encoding = System.Text.Encoding.UTF8;
 5             string result = null;
 6             //第一次Post请求,从输入获取参数
 7             result = client.OpenRead(remoteLoginUrl,string.Format(
 8                                                                             "username={0}&password={1}&login=",
 9                                                                             Util.GetTextString(UserNameTxt.Text, true), 
10                                                                             Util.GetTextString(PasswordTxt.Text, true)
11                                                                            )
12                                                    );
13             
14             //第二次Get请求,从第一次的response中获取cookie
15             client.RequestHeaders.Add("Cookie", client.Cookie);
16             Session["hasPosted"= client.Cookie;
17             result = client.OpenRead(remoteLoginUrl);
18             
19             //从返回结果中拿到带有auto_token的跳转链接
20             try
21             {
22                 int j = result.IndexOf("<a href=\"") + 9;
23                 int k = result.IndexOf("\">here</a>");
24                 Response.Redirect(result.Substring(j, k - j), false);
25             }
26             catch (Exception ex)
27             {
28                 string ss = ex.Message.ToString();
29                 Session["hasPosted"= null;
30                 Response.Redirect(string.Format("Error.aspx?errorCode={0}""LOGON_ERROR"));
31             }
32         }

proc实现。

HttpProc
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Net;
  5 using System.Net.Sockets;
  6 using System.Collections;
  7 using System.IO;
  8 using System.Text.RegularExpressions;
  9 using RE = System.Text.RegularExpressions.Regex;
 10 using System.Security.Cryptography.X509Certificates;
 11 
 12 /***************************************************************************************************************************************************
 13             HttpProc.WebClient client = new HttpProc.WebClient();
 14             client.Encoding = System.Text.Encoding.Default;//默认编码方式,根据需要设置其他类型
 15             client.OpenRead("http://www.baidu.com");//普通get请求
 16             MessageBox.Show(client.RespHtml);//获取返回的网页源代码
 17             client.DownloadFile("http://www.codepub.com/upload/163album.rar",@"C:\163album.rar");//下载文件
 18             client.OpenRead("http://passport.baidu.com/?login","username=zhangsan&password=123456");//提交表单,此处是登录百度的示例
 19             client.UploadFile("http://hiup.baidu.com/zhangsan/upload", @"file1=D:\1.mp3");//上传文件
 20             client.UploadFile("http://hiup.baidu.com/zhangsan/upload", "folder=myfolder&size=4003550",@"file1=D:\1.mp3");//提交含文本域和文件域的表单
 21 *****************************************************************************************************************************************************/
 22 
 23 namespace GHY.HttpProc
 24 {
 25     ///<summary>
 26     ///上传事件委托
 27     ///</summary>
 28     ///<param name="sender"></param>
 29     ///<param name="e"></param>
 30     public delegate void WebClientUploadEvent(object sender, HttpProc.UploadEventArgs e);
 31 
 32     ///<summary>
 33     ///下载事件委托
 34     ///</summary>
 35     ///<param name="sender"></param>
 36     ///<param name="e"></param>
 37     public delegate void WebClientDownloadEvent(object sender, HttpProc.DownloadEventArgs e);
 38 
 39 
 40     ///<summary>
 41     ///上传事件参数
 42     ///</summary>
 43     public struct UploadEventArgs
 44     {
 45         ///<summary>
 46         ///上传数据总大小
 47         ///</summary>
 48         public long totalBytes;
 49         ///<summary>
 50         ///已发数据大小
 51         ///</summary>
 52         public long bytesSent;
 53         ///<summary>
 54         ///发送进度(0-1)
 55         ///</summary>
 56         public double sendProgress;
 57         ///<summary>
 58         ///发送速度Bytes/s
 59         ///</summary>
 60         public double sendSpeed;
 61     }
 62 
 63     ///<summary>
 64     ///下载事件参数
 65     ///</summary>
 66     public struct DownloadEventArgs
 67     {
 68         ///<summary>
 69         ///下载数据总大小
 70         ///</summary>
 71         public long totalBytes;
 72         ///<summary>
 73         ///已接收数据大小
 74         ///</summary>
 75         public long bytesReceived;
 76         ///<summary>
 77         ///接收数据进度(0-1)
 78         ///</summary>
 79         public double ReceiveProgress;
 80         ///<summary>
 81         ///当前缓冲区数据
 82         ///</summary>
 83         public byte[] receivedBuffer;
 84         ///<summary>
 85         ///接收速度Bytes/s
 86         ///</summary>
 87         public double receiveSpeed;
 88     }
 89 
 90     ///<summary>
 91     ///实现向WEB服务器发送和接收数据
 92     ///</summary>
 93     public class WebClient
 94     {
 95         private WebHeaderCollection requestHeaders, responseHeaders;
 96         private TcpClient clientSocket;
 97         private MemoryStream postStream;
 98         private Encoding encoding = Encoding.Default;
 99         private const string BOUNDARY = "--HEDAODE--";
100         private const int SEND_BUFFER_SIZE = 10245;
101         private const int RECEIVE_BUFFER_SIZE = 10245;
102         private string cookie = "";
103         private string respHtml = "";
104         private string strRequestHeaders = "";
105         private string strResponseHeaders = "";
106         private int statusCode = 0;
107         private bool isCanceled = false;
108         public event WebClientUploadEvent UploadProgressChanged;
109         public event WebClientDownloadEvent DownloadProgressChanged;
110 
111         ///<summary>
112         ///初始化WebClient类
113         ///</summary>
114         public WebClient()
115         {
116             responseHeaders = new WebHeaderCollection();
117             requestHeaders = new WebHeaderCollection();
118         }
119 
120 
121         ///<summary>
122         ///读取指定URL的文本
123         ///</summary>
124         ///<param name="URL">请求的地址</param>
125         ///<returns>服务器响应文本</returns>
126         public string OpenRead(string URL)
127         {
128             requestHeaders.Add("Connection""close");
129             SendRequestData(URL, "GET");
130             return GetHtml();
131         }
132 
133 
134         //解决证书过期无法访问的问题
135         class CertPolicy : ICertificatePolicy
136         {
137             public bool CheckValidationResult(ServicePoint srvpt, X509Certificate cert, WebRequest req, int certprb)
138             { return true; }
139         }
140 
141         ///<summary>
142         ///采用https协议访问网络
143         ///</summary>
144         ///<param name="URL">url地址</param>
145         ///<param name="strPostdata">发送的数据</param>
146         ///<returns></returns>
147         public string OpenReadWithHttps(string URL, string strPostdata)
148         {
149             ServicePointManager.CertificatePolicy = new CertPolicy();
150             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
151             request.CookieContainer = new CookieContainer();
152             request.Method = "POST";
153             request.Accept = "*/*";
154             request.ContentType = "application/x-www-form-urlencoded";
155             byte[] buffer = this.encoding.GetBytes(strPostdata);
156             request.ContentLength = buffer.Length;
157             request.GetRequestStream().Write(buffer, 0, buffer.Length);
158             HttpWebResponse response = (HttpWebResponse)request.GetResponse();
159             StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);
160             this.respHtml = reader.ReadToEnd();
161             foreach (System.Net.Cookie ck in response.Cookies)
162             {
163                 this.cookie += ck.Name + "=" + ck.Value + ";";
164             }
165             reader.Close();
166             return respHtml;
167         }
168 
169         ///<summary>
170         ///读取指定URL的文本
171         ///</summary>
172         ///<param name="URL">请求的地址</param>
173         ///<param name="postData">向服务器发送的文本数据</param>
174         ///<returns>服务器响应文本</returns>
175         public string OpenRead(string URL, string postData)
176         {
177             byte[] sendBytes = encoding.GetBytes(postData);
178             postStream = new MemoryStream();
179             postStream.Write(sendBytes, 0, sendBytes.Length);
180 
181             requestHeaders.Add("Content-Length", postStream.Length.ToString());
182             requestHeaders.Add("Content-Type""application/x-www-form-urlencoded");
183             requestHeaders.Add("Connection""close");
184 
185             SendRequestData(URL, "POST");
186             return GetHtml();
187         }
188 
189 
190         ///<summary>
191         ///读取指定URL的流
192         ///</summary>
193         ///<param name="URL">请求的地址</param>
194         ///<param name="postData">向服务器发送的数据</param>
195         ///<returns>服务器响应流</returns>
196         public Stream GetStream(string URL, string postData)
197         {
198             byte[] sendBytes = encoding.GetBytes(postData);
199             postStream = new MemoryStream();
200             postStream.Write(sendBytes, 0, sendBytes.Length);
201 
202             requestHeaders.Add("Content-Length", postStream.Length.ToString());
203             requestHeaders.Add("Content-Type""application/x-www-form-urlencoded");
204             requestHeaders.Add("Connection""close");
205 
206             SendRequestData(URL, "POST");
207 
208             MemoryStream ms = new MemoryStream();
209             SaveNetworkStream(ms);
210             return ms;
211         }
212 
213 
214         ///<summary>
215         ///上传文件到服务器
216         ///</summary>
217         ///<param name="URL">请求的地址</param>
218         ///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>
219         ///<returns>服务器响应文本</returns>
220         public string UploadFile(string URL, string fileField)
221         {
222             return UploadFile(URL, "", fileField);
223         }
224 
225         ///<summary>
226         ///上传文件和数据到服务器
227         ///</summary>
228         ///<param name="URL">请求地址</param>
229         ///<param name="textField">文本域(格式为:name1=value1&name2=value2)</param>
230         ///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>
231         ///<returns>服务器响应文本</returns>
232         public string UploadFile(string URL, string textField, string fileField)
233         {
234             postStream = new MemoryStream();
235 
236             if (textField != "" && fileField != "")
237             {
238                 WriteTextField(textField);
239                 WriteFileField(fileField);
240             }
241             else if (fileField != "")
242             {
243                 WriteFileField(fileField);
244             }
245             else if (textField != "")
246             {
247                 WriteTextField(textField);
248             }
249             else
250                 throw new Exception("文本域和文件域不能同时为空。");
251 
252             //写入结束标记
253             byte[] buffer = encoding.GetBytes("--" + BOUNDARY + "--\r\n");
254             postStream.Write(buffer, 0, buffer.Length);
255 
256             //添加请求标头
257             requestHeaders.Add("Content-Length", postStream.Length.ToString());
258             requestHeaders.Add("Content-Type""multipart/form-data; boundary=" + BOUNDARY);
259             requestHeaders.Add("Connection""Keep-Alive");
260 
261             //发送请求数据
262             SendRequestData(URL, "POST"true);
263 
264             //返回响应文本
265             return GetHtml();
266         }
267 
268 
269         ///<summary>
270         ///分析文本域,添加到请求流
271         ///</summary>
272         ///<param name="textField">文本域</param>
273         private void WriteTextField(string textField)
274         {
275             string[] strArr = RE.Split(textField, "&");
276             textField = "";
277             foreach (string var in strArr)
278             {
279                 Match M = RE.Match(var, "([^=]+)=(.+)");
280                 textField += "--" + BOUNDARY + "\r\n";
281                 textField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"\r\n\r\n" + M.Groups[2].Value + "\r\n";
282             }
283             byte[] buffer = encoding.GetBytes(textField);
284             postStream.Write(buffer, 0, buffer.Length);
285         }
286 
287         ///<summary>
288         ///分析文件域,添加到请求流
289         ///</summary>
290         ///<param name="fileField">文件域</param>
291         private void WriteFileField(string fileField)
292         {
293             string filePath = "";
294             int count = 0;
295             string[] strArr = RE.Split(fileField, "&");
296             foreach (string var in strArr) {
297                 Match M = RE.Match(var, "([^=]+)=(.+)");
298                 filePath = M.Groups[2].Value;
299                 fileField = "--" + BOUNDARY + "\r\n";
300                 fileField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"; filename=\"" + Path.GetFileName(filePath) + "\"\r\n";
301                 fileField += "Content-Type: image/jpeg\r\n\r\n";
302  
303                 byte[] buffer = encoding.GetBytes(fileField);
304                 postStream.Write(buffer, 0, buffer.Length);
305  
306                 //添加文件数据
307                 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
308                 buffer = new byte[50000];
309  
310                 do
311                 {
312                     count = fs.Read(buffer, 0, buffer.Length);
313                     postStream.Write(buffer, 0, count);
314  
315                 } while (count > 0);
316  
317                 fs.Close();
318                 fs.Dispose();
319                 fs = null;
320  
321                 buffer = encoding.GetBytes("\r\n");
322                 postStream.Write(buffer, 0, buffer.Length);
323             }
324         }
325 
326         ///<summary>
327         ///从指定URL下载数据流
328         ///</summary>
329         ///<param name="URL">请求地址</param>
330         ///<returns>数据流</returns>
331         public Stream DownloadData(string URL)
332         {
333             requestHeaders.Add("Connection""close");
334             SendRequestData(URL, "GET");
335             MemoryStream ms = new MemoryStream();
336             SaveNetworkStream(ms, true);
337             return ms;
338         }
339 
340 
341         ///<summary>
342         ///从指定URL下载文件
343         ///</summary>
344         ///<param name="URL">文件URL地址</param>
345         ///<param name="fileName">文件保存路径,含文件名(如:C:\test.jpg)</param>
346         public void DownloadFile(string URL, string fileName)
347         {
348             requestHeaders.Add("Connection""close");
349             SendRequestData(URL, "GET");
350             FileStream fs = new FileStream(fileName, FileMode.Create);
351             SaveNetworkStream(fs, true);
352             fs.Close();
353             fs = null;
354         }
355 
356         ///<summary>
357         ///向服务器发送请求
358         ///</summary>
359         ///<param name="URL">请求地址</param>
360         ///<param name="method">POST或GET</param>
361         ///<param name="showProgress">是否显示上传进度</param>
362         private void SendRequestData(string URL, string method, bool showProgress)
363         {
364             clientSocket = new TcpClient();
365             Uri URI = new Uri(URL);
366             clientSocket.Connect(URI.Host, URI.Port);
367 
368             requestHeaders.Add("Host", URI.Host);
369             byte[] request = GetRequestHeaders(method + " " + URI.PathAndQuery + " HTTP/1.1");
370             clientSocket.Client.Send(request);
371 
372             //若有实体内容就发送它
373             if (postStream != null)
374             {
375                 byte[] buffer = new byte[SEND_BUFFER_SIZE];
376                 int count = 0;
377                 Stream sm = clientSocket.GetStream();
378                 postStream.Position = 0;
379 
380                 UploadEventArgs e = new UploadEventArgs();
381                 e.totalBytes = postStream.Length;
382                 System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();//计时器
383                 timer.Start();
384                 do
385                 {
386                     //如果取消就推出
387                     if (isCanceled) { break; }
388 
389                     //读取要发送的数据
390                     count = postStream.Read(buffer, 0, buffer.Length);
391                     //发送到服务器
392                     sm.Write(buffer, 0, count);
393 
394                     //是否显示进度
395                     if (showProgress)
396                     {
397                         //触发事件
398                         e.bytesSent += count;
399                         e.sendProgress = (double)e.bytesSent / (double)e.totalBytes;
400                         double t = timer.ElapsedMilliseconds / 1000;
401                         t = t <= 0 ? 1 : t;
402                         e.sendSpeed = (double)e.bytesSent / t;
403                         if (UploadProgressChanged != null) { UploadProgressChanged(this, e); }
404                     }
405 
406                 } while (count > 0);
407                 timer.Stop();
408                 postStream.Close();
409                 //postStream.Dispose();
410                 postStream = null;
411 
412             }//end if
413 
414         }
415 
416         ///<summary>
417         ///向服务器发送请求
418         ///</summary>
419         ///<param name="URL">请求URL地址</param>
420         ///<param name="method">POST或GET</param>
421         private void SendRequestData(string URL, string method)
422         {
423             SendRequestData(URL, method, false);
424         }
425 
426 
427         ///<summary>
428         ///获取请求头字节数组
429         ///</summary>
430         ///<param name="request">POST或GET请求</param>
431         ///<returns>请求头字节数组</returns>
432         private byte[] GetRequestHeaders(string request)
433         {
434             requestHeaders.Add("Accept""*/*");
435             requestHeaders.Add("Accept-Language""zh-cn");
436             requestHeaders.Add("User-Agent""Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
437 
438             string headers = request + "\r\n";
439 
440             foreach (string key in requestHeaders)
441             {
442                 headers += key + ":" + requestHeaders[key] + "\r\n";
443             }
444 
445             //有Cookie就带上Cookie
446             if (cookie != "") { headers += "Cookie:" + cookie + "\r\n"; }
447 
448             //空行,请求头结束
449             headers += "\r\n";
450 
451             strRequestHeaders = headers;
452             requestHeaders.Clear();
453             return encoding.GetBytes(headers);
454         }
455 
456 
457 
458         ///<summary>
459         ///获取服务器响应文本
460         ///</summary>
461         ///<returns>服务器响应文本</returns>
462         private string GetHtml()
463         {
464             MemoryStream ms = new MemoryStream();
465             SaveNetworkStream(ms);//将网络流保存到内存流
466             StreamReader sr = new StreamReader(ms, encoding);
467             respHtml = sr.ReadToEnd();
468             sr.Close(); ms.Close();
469             return respHtml;
470         }
471 
472         ///<summary>
473         ///将网络流保存到指定流
474         ///</summary>
475         ///<param name="toStream">保存位置</param>
476         ///<param name="needProgress">是否显示进度</param>
477         private void SaveNetworkStream(Stream toStream, bool showProgress)
478         {
479             //获取要保存的网络流
480             NetworkStream NetStream = clientSocket.GetStream();
481 
482             byte[] buffer = new byte[RECEIVE_BUFFER_SIZE];
483             int count = 0, startIndex = 0;
484 
485             MemoryStream ms = new MemoryStream();
486             for (int i = 0; i < 3; i++)
487             {
488                 count = NetStream.Read(buffer, 0500);
489                 ms.Write(buffer, 0, count);
490             }
491 
492             if (ms.Length == 0) { NetStream.Close(); throw new Exception("远程服务器没有响应"); }
493 
494             buffer = ms.GetBuffer();
495             count = (int)ms.Length;
496 
497             GetResponseHeader(buffer, out startIndex);//分析响应,获取响应头和响应实体
498             count -= startIndex;
499             toStream.Write(buffer, startIndex, count);
500 
501             DownloadEventArgs e = new DownloadEventArgs();
502 
503             if (responseHeaders["Content-Length"!= null)
504             { e.totalBytes = long.Parse(responseHeaders["Content-Length"]); }
505             else
506             { e.totalBytes = -1; }
507 
508             //启动计时器
509             System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
510             timer.Start();
511 
512             do
513             {
514                 //如果取消就推出
515                 if (isCanceled) { break; }
516 
517                 //显示下载进度
518                 if (showProgress)
519                 {
520                     e.bytesReceived += count;
521                     e.ReceiveProgress = (double)e.bytesReceived / (double)e.totalBytes;
522 
523                     byte[] tempBuffer = new byte[count];
524                     Array.Copy(buffer, startIndex, tempBuffer, 0, count);
525                     e.receivedBuffer = tempBuffer;
526 
527                     double t = (timer.ElapsedMilliseconds + 0.1/ 1000;
528                     e.receiveSpeed = (double)e.bytesReceived / t;
529 
530                     startIndex = 0;
531                     if (DownloadProgressChanged != null) { DownloadProgressChanged(this, e); }
532                 }
533 
534                 //读取网路数据到缓冲区
535                 count = NetStream.Read(buffer, 0, buffer.Length);
536 
537                 //将缓存区数据保存到指定流
538                 toStream.Write(buffer, 0, count);
539             } while (count > 0);
540 
541             timer.Stop();//关闭计时器
542 
543             if (responseHeaders["Content-Length"!= null)
544             {
545                 toStream.SetLength(long.Parse(responseHeaders["Content-Length"]));
546             }
547             //else
548             //{
549             //    toStream.SetLength(toStream.Length);
550             //    responseHeaders.Add("Content-Length", toStream.Length.ToString());//添加响应标头
551             //}
552 
553             toStream.Position = 0;
554 
555             //关闭网络流和网络连接
556             NetStream.Close();
557             clientSocket.Close();
558         }
559 
560 
561         ///<summary>
562         ///将网络流保存到指定流
563         ///</summary>
564         ///<param name="toStream">保存位置</param>
565         private void SaveNetworkStream(Stream toStream)
566         {
567             SaveNetworkStream(toStream, false);
568         }
569 
570 
571 
572         ///<summary>
573         ///分析响应流,去掉响应头
574         ///</summary>
575         ///<param name="buffer"></param>
576         private void GetResponseHeader(byte[] buffer, out int startIndex)
577         {
578             responseHeaders.Clear();
579             string html = encoding.GetString(buffer);
580             StringReader sr = new StringReader(html);
581  
582             int start = html.IndexOf("\r\n\r\n"+ 4;//找到空行位置
583             strResponseHeaders = html.Substring(0, start);//获取响应头文本
584  
585             //获取响应状态码
586             //
587             if (sr.Peek() > -1)
588             {
589                 //读第一行字符串
590                 string line = sr.ReadLine();
591  
592                 //分析此行字符串,获取服务器响应状态码
593                 Match M = RE.Match(line, @"\d\d\d");
594                 if (M.Success)
595                 {
596                     statusCode = int.Parse(M.Value);
597                 }
598             }
599  
600             //获取响应头
601             //
602             while (sr.Peek() > -1)
603             {
604                 //读一行字符串
605                 string line = sr.ReadLine();
606  
607                 //若非空行
608                 if (line != "")
609                 {
610                     //分析此行字符串,获取响应标头
611                     Match M = RE.Match(line, "([^:]+):(.+)");
612                     if (M.Success)
613                     {
614                         try
615                         {        //添加响应标头到集合
616                             responseHeaders.Add(M.Groups[1].Value.Trim(), M.Groups[2].Value.Trim());
617                         }
618                         catch
619                         { }
620  
621  
622                         //获取Cookie
623                         if (M.Groups[1].Value == "Set-Cookie")
624                         {
625                             M = RE.Match(M.Groups[2].Value, "[^=]+=[^;]+");
626                             cookie += M.Value.Trim() + ";";
627                         }
628                     }
629  
630                 }
631                 //若是空行,代表响应头结束响应实体开始。(响应头和响应实体间用一空行隔开)
632                 else
633                 {
634                     //如果响应头中没有实体大小标头,尝试读响应实体第一行获取实体大小
635                     if (responseHeaders["Content-Length"== null && sr.Peek() > -1)
636                     {
637                         //读响应实体第一行
638                         line = sr.ReadLine();
639  
640                         //分析此行看是否包含实体大小
641                         Match M = RE.Match(line, "~[0-9a-fA-F]{1,15}");
642  
643                         if (M.Success)
644                         {
645                             //将16进制的实体大小字符串转换为10进制
646                             int length = int.Parse(M.Value, System.Globalization.NumberStyles.AllowHexSpecifier);
647                             responseHeaders.Add("Content-Length", length.ToString());//添加响应标头
648                             strResponseHeaders += M.Value + "\r\n";
649                         }
650                     }
651                     break;//跳出循环
652                 }//End If
653             }//End While
654  
655             sr.Close();
656  
657             //实体开始索引
658             startIndex = encoding.GetBytes(strResponseHeaders).Length;
659         }
660 
661 
662         ///<summary>
663         ///取消上传或下载,要继续开始请调用Start方法
664         ///</summary>
665         public void Cancel()
666         {
667             isCanceled = true;
668         }
669 
670         ///<summary>
671         ///启动上传或下载,要取消请调用Cancel方法
672         ///</summary>
673         public void Start()
674         {
675             isCanceled = false;
676         }
677 
678         //*************************************************************
679         //以下为属性
680         //*************************************************************
681 
682         ///<summary>
683         ///获取或设置请求头
684         ///</summary>
685         public WebHeaderCollection RequestHeaders
686         {
687             set { requestHeaders = value; }
688             get { return requestHeaders; }
689         }
690 
691         ///<summary>
692         ///获取响应头集合
693         ///</summary>
694         public WebHeaderCollection ResponseHeaders
695         {
696             get { return responseHeaders; }
697         }
698 
699         ///<summary>
700         ///获取请求头文本
701         ///</summary>
702         public string StrRequestHeaders
703         {
704             get { return strRequestHeaders; }
705         }
706 
707         ///<summary>
708         ///获取响应头文本
709         ///</summary>
710         public string StrResponseHeaders
711         {
712             get { return strResponseHeaders; }
713         }
714 
715         ///<summary>
716         ///获取或设置Cookie
717         ///</summary>
718         public string Cookie
719         {
720             set { cookie = value; }
721             get { return cookie; }
722         }
723 
724         ///<summary>
725         ///获取或设置编码方式(默认为系统默认编码方式)
726         ///</summary>
727         public Encoding Encoding
728         {
729             set { encoding = value; }
730             get { return encoding; }
731         }
732 
733         ///<summary>
734         ///获取服务器响应文本
735         ///</summary>
736         public string RespHtml
737         {
738             get { return respHtml; }
739         }
740 
741 
742         ///<summary>
743         ///获取服务器响应状态码
744         ///</summary>
745         public int StatusCode
746         {
747             get { return statusCode; }
748         }
749     }
750 }