1 /// 2 /// Author: [ ChengKing(ZhengJian) ] 3 /// Blog: Http://blog.csdn.net/ChengKing 4 /// 注:从网上找了个优秀代码 5 /// 扩展如下功能: 6 /// 1. 解决一些线程相关的Bug; 7 /// 2.扩展用控制文件实现断点续传功能. 8 /// 9 namespace DownLoadComponent 10 { 11 /// 12 /// 多线程辅助类(Add by ChengKing) 13 /// 14 public class Task 15 { 16 string _FromFileName; 17 string _ToFileName; 18 int _ThreadNum; 19 20 public Task(string FromFileName, string ToFileName, int ThreadNum) 21 { 22 this._FromFileName = FromFileName; 23 this._ToFileName = ToFileName; 24 this._ThreadNum = ThreadNum; 25 } 26 27 public string FromFileName 28 { 29 get 30 { 31 return _FromFileName; 32 } 33 set 34 { 35 _FromFileName = value; 36 } 37 } 38 public string ToFileName 39 { 40 get 41 { 42 return _ToFileName; 43 } 44 set 45 { 46 _ToFileName = value; 47 } 48 } 49 public int ThreadNum 50 { 51 get 52 { 53 return _ThreadNum; 54 } 55 set 56 { 57 _ThreadNum = value; 58 } 59 } 60 } 61 62 /// 63 /// 记录下载的字节位置 64 /// 65 public class DownLoadState 66 { 67 private string _FileName; 68 69 private string _AttachmentName; 70 private int _Position; 71 private string _RequestURL; 72 private string _ResponseURL; 73 private int _Length; 74 75 private byte[] _Data; 76 77 public string FileName 78 { 79 get 80 { 81 return _FileName; 82 } 83 } 84 85 public int Position 86 { 87 get 88 { 89 return _Position; 90 } 91 } 92 93 public int Length 94 { 95 get 96 { 97 return _Length; 98 } 99 } 100 101 102 public string AttachmentName 103 { 104 get 105 { 106 return _AttachmentName; 107 } 108 } 109 110 public string RequestURL 111 { 112 get 113 { 114 return _RequestURL; 115 } 116 } 117 118 public string ResponseURL 119 { 120 get 121 { 122 return _ResponseURL; 123 } 124 } 125 126 127 public byte[] Data 128 { 129 get 130 { 131 return _Data; 132 } 133 } 134 135 internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length, byte[] Data) 136 { 137 this._FileName = FileName; 138 this._RequestURL = RequestURL; 139 this._ResponseURL = ResponseURL; 140 this._AttachmentName = AttachmentName; 141 this._Position = Position; 142 this._Data = Data; 143 this._Length = Length; 144 } 145 146 internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length, ThreadCallbackHandler tch) 147 { 148 this._RequestURL = RequestURL; 149 this._ResponseURL = ResponseURL; 150 this._FileName = FileName; 151 this._AttachmentName = AttachmentName; 152 this._Position = Position; 153 this._Length = Length; 154 this._ThreadCallback = tch; 155 } 156 157 internal DownLoadState(string RequestURL, string ResponseURL, string FileName, string AttachmentName, int Position, int Length) 158 { 159 this._RequestURL = RequestURL; 160 this._ResponseURL = ResponseURL; 161 this._FileName = FileName; 162 this._AttachmentName = AttachmentName; 163 this._Position = Position; 164 this._Length = Length; 165 } 166 167 private ThreadCallbackHandler _ThreadCallback; 168 169 // 170 internal void StartDownloadFileChunk() 171 { 172 if (this._ThreadCallback != null) 173 { 174 this._ThreadCallback(this._RequestURL, this._FileName, this._Position, this._Length); 175 } 176 } 177 178 } 179 180 //委托代理线程的所执行的方法签名一致 181 public delegate void ThreadCallbackHandler(string S, string s, int I, int i); 182 183 //异常处理动作 184 public enum ExceptionActions 185 { 186 Throw, 187 CancelAll, 188 Ignore, 189 Retry 190 } 191 192 /// 193 /// 包含 Exception 事件数据的类 194 /// 195 public class ExceptionEventArgs : System.EventArgs 196 { 197 private System.Exception _Exception; 198 private ExceptionActions _ExceptionAction; 199 200 private DownLoadState _DownloadState; 201 202 public DownLoadState DownloadState 203 { 204 get 205 { 206 return _DownloadState; 207 } 208 } 209 210 public Exception Exception 211 { 212 get 213 { 214 return _Exception; 215 } 216 } 217 218 public ExceptionActions ExceptionAction 219 { 220 get 221 { 222 return _ExceptionAction; 223 } 224 set 225 { 226 _ExceptionAction = value; 227 } 228 } 229 230 internal ExceptionEventArgs(System.Exception e, DownLoadState DownloadState) 231 { 232 this._Exception = e; 233 this._DownloadState = DownloadState; 234 } 235 } 236 237 /// 238 /// 包含 DownLoad 事件数据的类 239 /// 240 public class DownLoadEventArgs : System.EventArgs 241 { 242 private DownLoadState _DownloadState; 243 244 public DownLoadState DownloadState 245 { 246 get 247 { 248 return _DownloadState; 249 } 250 } 251 252 public DownLoadEventArgs(DownLoadState DownloadState) 253 { 254 this._DownloadState = DownloadState; 255 } 256 257 } 258 259 /// 260 /// 支持断点续传多线程下载的类 261 /// 262 public class HttpWebClient 263 { 264 private static object _SyncLockObject = new object(); 265 266 public delegate void DataReceiveEventHandler(HttpWebClient Sender, DownLoadEventArgs e); 267 268 public event DataReceiveEventHandler DataReceive; //接收字节数据事件 269 270 public delegate void ExceptionEventHandler(HttpWebClient Sender, ExceptionEventArgs e); 271 272 public event ExceptionEventHandler ExceptionOccurrs; //发生异常事件 273 274 private int _FileLength; //下载文件的总大小 275 276 public static ArrayList threads; 277 278 public int FileLength 279 { 280 get 281 { 282 return _FileLength; 283 } 284 } 285 286 /// 287 /// 分块下载文件 288 /// 289 /// URL 地址 290 /// 保存到本地的路径文件名 291 /// 块数,线程数 292 public void DownloadFile(string Address, string FileName, int ChunksCount) 293 { 294 int p = 0; // position 295 int s = 0; // chunk size 296 string a = null; 297 HttpWebRequest hwrq; 298 HttpWebResponse hwrp = null; 299 try 300 { 301 302 hwrq = (HttpWebRequest)WebRequest.Create(this.GetUri(Address)); 303 //hwrq.Timeout = 20000000; 304 //if (hwrq.HaveResponse == false) 305 // return; 306 //hwrq.ProtocolVersion =HttpVersion.Version10; 307 //WebProxy wp = WebProxy.GetDefaultProxy(); 308 //hwrq.Proxy = wp; 309 hwrq.Method = "GET"; 310 try 311 { 312 hwrp = (HttpWebResponse)hwrq.GetResponse(); 313 } 314 catch (Exception e) 315 { 316 throw new Exception(e.Message); 317 } 318 319 long L = hwrp.ContentLength; 320 321 //如果文件太小, 就不用分多线程, 用一个线程下载即可. (目前控制在800K) 322 //if (L < 800000) 323 //{ 324 // ChunksCount = 1; 325 //} 326 327 hwrq.Credentials = this.m_credentials; 328 329 L = ((L == -1) || (L > 0x7fffffff)) ? ((long)0x7fffffff) : L; //Int32.MaxValue 该常数的值为 2,147,483,647; 即十六进制的 0x7FFFFFFF 330 331 int l = (int)L; 332 333 this._FileLength = l; 334 335 bool b = (hwrp.Headers["Accept-Ranges"] != null & hwrp.Headers["Accept-Ranges"] == "bytes"); 336 a = hwrp.Headers["Content-Disposition"]; //attachment 337 if (a != null) 338 { 339 a = a.Substring(a.LastIndexOf("filename=") + 9); 340 } 341 else 342 { 343 a = FileName; 344 } 345 346 int ss = s; 347 if (b) 348 { 349 if (ExistControlFile(FileName)) //是否存在文件 350 { 351 string[] strBlocks = this.ReadInfFromControlFile(FileName).Split(new char[2] { '/r', '/n' }); 352 for (int i = 0; i < strBlocks.Length; i++) 353 { 354 if (strBlocks[i].Trim().Length != 0 && strBlocks[i].Substring(strBlocks[i].Length - 1) == "0") 355 { 356 string[] strRecord = strBlocks[i].Split(','); 357 int p2 = int.Parse(strRecord[0]); 358 int s2 = int.Parse(strRecord[1]); 359 DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p2, s2, new ThreadCallbackHandler(this.DownloadFileChunk)); 360 Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk)); 361 if (threads == null) 362 { 363 threads = new ArrayList(); 364 } 365 threads.Add(t); 366 t.Start(); 367 } 368 369 370 } 371 372 } 373 else 374 { 375 //建立控制文件 376 FileStream fs = File.Create(this.GetControlFileName(FileName)); 377 fs.Close(); 378 379 if (File.Exists(FileName)) 380 { 381 FileInfo fi = new FileInfo(FileName); 382 if (fi.Length == L) 383 { 384 this.AddendInfToControlFile(FileName, 0, 0); 385 this.UpdateControlFile(FileName, 0, 0); 386 return; 387 } 388 } 389 390 s = l / ChunksCount; 391 if (s < 2 * 64 * 1024) //块大小至少为 128 K 字节 392 { 393 s = 2 * 64 * 1024; 394 } 395 ss = s; 396 int i = 0; 397 while (l >= s) 398 { 399 l -= s; 400 if (l < s) 401 { 402 s += l; 403 } 404 if (i++ > 0) 405 { 406 DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s, new ThreadCallbackHandler(this.DownloadFileChunk)); 407 408 AddendInfToControlFile(FileName, p, s); 409 Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk)); 410 if (threads == null) 411 { 412 threads = new ArrayList(); 413 } 414 threads.Add(t); 415 t.Start(); 416 417 } 418 p += s; 419 } 420 s = ss; 421 422 AddendInfToControlFile(FileName, 0, s); 423 DownLoadState x1 = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, 0, s, new ThreadCallbackHandler(this.DownloadFileChunk)); 424 Thread t2 = new Thread(new ThreadStart(x1.StartDownloadFileChunk)); 425 if (threads == null) 426 { 427 threads = new ArrayList(); 428 } 429 threads.Add(t2); 430 t2.Start(); 431 } 432 } 433 //如果服务器不支持断点续传(Accept-Range), 则使用单线程下载 434 else 435 { 436 AddendInfToControlFile(FileName, 0, l); 437 DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, 0, l, new ThreadCallbackHandler(this.DownloadFileChunk)); 438 Thread t = new Thread(new ThreadStart(x.StartDownloadFileChunk)); 439 if (threads == null) 440 { 441 threads = new ArrayList(); 442 } 443 threads.Add(t); 444 t.Start(); 445 } 446 } 447 catch (Exception e) 448 { 449 //if (blnReturn == true) 450 //{ 451 // return; 452 //} 453 454 ExceptionActions ea = ExceptionActions.Throw; 455 if (ea == ExceptionActions.Throw) 456 { 457 if (!(e is WebException) && !(e is SecurityException)) 458 { 459 throw new WebException("net_webclient", e); 460 } 461 throw; 462 } 463 464 465 //if (this.ExceptionOccurrs != null) 466 //{ 467 // DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s); 468 469 // ExceptionEventArgs eea = new ExceptionEventArgs(e, x); 470 // ExceptionOccurrs(this, eea); 471 // ea = eea.ExceptionAction; 472 //} 473 474 } 475 476 } 477 478 #region 操作控制文件(By King Zheng) 479 480 /// 481 /// 插入文件块信息到控制文件(Add by ChengKing) 482 /// 483 /// 484 /// 485 /// 486 private void AddendInfToControlFile(string FileName, int Position, int Length) 487 { 488 489 490 try 491 { 492 lock (_SyncLockObject) 493 { 494 string strControlFile = GetControlFileName(FileName); 495 496 497 //if (File.Exists(strControlFile) == false) 498 //{ 499 // return; 500 //} 501 502 using (StreamWriter sw = new StreamWriter(strControlFile, true, Encoding.Default)) 503 { 504 //sw.NewLine = "$"; 505 sw.WriteLine(Position.ToString() + "," + Length.ToString() + "," + "0"); 506 } 507 //using (System.IO.FileStream sw = new System.IO.FileStream(strControlFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite)) 508 //{ 509 // //sw.Position = e.DownloadState.Position; 510 // sw.Write(Position.ToString() + "," + Length.ToString() + "," + "0"); 511 // sw.Close(); 512 //} 513 514 515 516 } 517 } 518 catch (Exception e) 519 { 520 throw new Exception("写控制文件出错!" + e.Message); 521 } 522 523 } 524 525 /// 526 /// 更新控制文件(Add by ChengKing) 527 /// 528 /// 529 /// 530 /// 531 private void UpdateControlFile(string FileName, int Position, int Length) 532 { 533 try 534 { 535 lock (_SyncLockObject) 536 { 537 string strControlFile = GetControlFileName(FileName); 538 539 540 //if (File.Exists(strControlFile) == false) 541 //{ 542 // return; 543 //} 544 545 string s = null; 546 using (StreamReader sr = new System.IO.StreamReader(strControlFile)) 547 { 548 s = sr.ReadToEnd(); 549 s = s.Replace(Position.ToString() + "," + Length.ToString() + "," + "0", Position.ToString() + "," + Length.ToString() + "," + "1"); 550 } 551 using (StreamWriter sw = new StreamWriter(strControlFile, false, Encoding.Default)) 552 { 553 sw.WriteLine(s); 554 } 555 } 556 } 557 catch (Exception e) 558 { 559 throw new Exception("更新控制文件出错!" + e.Message); 560 } 561 562 } 563 564 /// 565 /// 读取所有信息从控制文件(Add by ChengKing) 566 /// 567 /// 568 /// 569 private string ReadInfFromControlFile(string FileName) 570 { 571 try 572 { 573 lock (_SyncLockObject) 574 { 575 string strControlFile = GetControlFileName(FileName); 576 577 string s = null; 578 using (StreamReader sr = new System.IO.StreamReader(strControlFile)) 579 { 580 s = sr.ReadToEnd(); 581 582 } 583 return s; 584 } 585 } 586 catch (Exception e) 587 { 588 throw new Exception("读控制文件出错!" + e.Message); 589 } 590 } 591 592 /// 593 /// 根据目标文件名得到控制文件名(Add by ChengKing) 594 /// 595 /// 596 /// 597 public string GetControlFileName(string FileName) 598 { 599 string strPath = Path.GetDirectoryName(FileName); 600 601 //string strFileNameWithoutExtension = Path.GetFileNameWithoutExtension(FileName); 602 string strFileNameWithoutExtension = Path.GetFileName(FileName); 603 string strControlFile = Path.Combine(strPath, strFileNameWithoutExtension + "_Control.txt"); 604 return strControlFile; 605 } 606 607 /// 608 /// 判断控制文件是否存在 609 /// 610 /// 611 /// 612 private bool ExistControlFile(string FileName) 613 { 614 string strControlFile = GetControlFileName(FileName); 615 if (File.Exists(strControlFile)) 616 { 617 return true; 618 } 619 return false; 620 } 621 622 /// 623 /// 判断控制文件是否完成 624 /// 625 /// 626 /// 627 public bool JudgeControlFileIfFinished(string strControlFile) 628 { 629 try 630 { 631 string s = null; 632 lock (_SyncLockObject) 633 { 634 using (StreamReader sr = new System.IO.StreamReader(strControlFile)) 635 { 636 s = sr.ReadToEnd(); 637 } 638 } 639 if (s + String.Empty == String.Empty) 640 { 641 return false; 642 } 643 string[] strBlocks = s.Split(new char[2] { '/r', '/n' }); 644 for (int i = 0; i < strBlocks.Length; i++) 645 { 646 if (strBlocks[i].Trim().Length != 0 && strBlocks[i].Substring(strBlocks[i].Length - 1) == "0") 647 { 648 return false; 649 } 650 } 651 return true; 652 653 } 654 catch (Exception e) 655 { 656 throw new Exception("判断控制文件是否完成时, 读取文件出错!" + e.Message); 657 } 658 } 659 660 /// 661 /// 删除控制文件(Add by ChengKing) 662 /// 663 /// 664 /// 665 public bool DeleteControlFile(string strControlFile) 666 { 667 try 668 { 669 lock (_SyncLockObject) 670 { 671 if (File.Exists(strControlFile)) 672 { 673 File.Delete(strControlFile); 674 } 675 } 676 return true; 677 } 678 catch (Exception e) 679 { 680 throw new Exception("删除控制文件出错!" + e.Message); 681 } 682 } 683 684 #endregion 685 686 /// 687 /// 下载一个文件块,利用该方法可自行实现多线程断点续传 688 /// 689 /// URL 地址 690 /// 保存到本地的路径文件名 691 /// 块大小 692 public void DownloadFileChunk(string Address, string FileName, int FromPosition, int Length) 693 { 694 HttpWebResponse hwrp = null; 695 string a = null; 696 try 697 { 698 //this._FileName = FileName; 699 HttpWebRequest hwrq = (HttpWebRequest)WebRequest.Create(this.GetUri(Address)); 700 //hwrq.Credentials = this.m_credentials; 701 702 hwrq.AddRange(FromPosition); 703 704 hwrp = (HttpWebResponse)hwrq.GetResponse(); 705 706 //hwrp.Headers.Add("Content-Range", FromPosition.ToString()); //Test 707 708 a = hwrp.Headers["Content-Disposition"]; //attachment 709 if (a != null) 710 { 711 a = a.Substring(a.LastIndexOf("filename=") + 9); 712 } 713 else 714 { 715 a = FileName; 716 } 717 718 byte[] buffer = this.ResponseAsBytes(Address, hwrp, Length, FileName); 719 // lock (_SyncLockObject) 720 // { 721 // this._Bytes += buffer.Length; 722 // } 723 } 724 catch (Exception e) 725 { 726 ExceptionActions ea = ExceptionActions.Throw; 727 if (this.ExceptionOccurrs != null) 728 { 729 DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, FromPosition, Length); 730 ExceptionEventArgs eea = new ExceptionEventArgs(e, x); 731 ExceptionOccurrs(this, eea); 732 ea = eea.ExceptionAction; 733 } 734 735 if (ea == ExceptionActions.Throw) 736 { 737 if (!(e is WebException) && !(e is SecurityException)) 738 { 739 throw new WebException("net_webclient", e); 740 } 741 throw; 742 } 743 } 744 } 745 746 internal byte[] ResponseAsBytes(string RequestURL, WebResponse Response, long Length, string FileName) 747 { 748 string a = null; //AttachmentName 749 int P = 0; //整个文件的位置指针 750 int num2 = 0; 751 int num3 = 0; 752 int intFrom = 0; 753 try 754 { 755 a = Response.Headers["Content-Disposition"]; //attachment 756 if (a != null) 757 { 758 a = a.Substring(a.LastIndexOf("filename=") + 9); 759 } 760 761 long num1 = Length; //Response.ContentLength; 762 bool flag1 = false; 763 if (num1 == -1) 764 { 765 flag1 = true; 766 num1 = 0x10000; //64k 767 } 768 byte[] buffer1 = new byte[(long)num1]; 769 770 771 int p = 0; //本块的位置指针 772 773 string s = Response.Headers["Content-Range"]; 774 //string s = hwrq.Headers["Range"]; 775 776 if (s != null) 777 { 778 s = s.Replace("bytes ", ""); 779 s = s.Substring(0, s.IndexOf("-")); 780 P = Convert.ToInt32(s); 781 intFrom = P; 782 783 } 784 785 //int num3 = 0; 786 787 Stream S = Response.GetResponseStream(); 788 789 int count = 0; 790 791 int bufferSize = 65535; //允许读取的最大字节 792 793 int times; 794 do 795 { 796 times = 0; 797 798 //num2 = S.Read(buffer1, num3, ((int)num1) - num3); 799 800 //限制最大读取字节 801 if (bufferSize < ((int)num1) - num3) 802 { 803 num2 = S.Read(buffer1, num3, bufferSize); 804 } 805 else 806 { 807 num2 = S.Read(buffer1, num3, ((int)num1) - num3); 808 } 809 810 //网络短时间的不稳定 811 if (num2 == 0) 812 { 813 Thread.Sleep(50); 814 times++; 815 816 if (times > 100) 817 { 818 throw new Exception("网络传输层错误"); 819 } 820 821 } 822 823 num3 += num2; 824 if (flag1 && (num3 == num1)) 825 { 826 num1 += 0x10000; 827 byte[] buffer2 = new byte[(int)num1]; 828 Buffer.BlockCopy(buffer1, 0, buffer2, 0, num3); 829 buffer1 = buffer2; 830 } 831 832 // lock (_SyncLockObject) 833 // { 834 // this._bytes += num2; 835 // } 836 if (num2 > 0) 837 { 838 if (this.DataReceive != null) 839 { 840 byte[] buffer = new byte[num2]; 841 Buffer.BlockCopy(buffer1, p, buffer, 0, buffer.Length); 842 DownLoadState dls = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2, buffer); 843 DownLoadEventArgs dlea = new DownLoadEventArgs(dls); 844 845 //触发事件 846 this.OnDataReceive(dlea); 847 //System.Threading.Thread.Sleep(100); 848 849 } 850 p += num2; //本块的位置指针 851 P += num2; //整个文件的位置指针 852 } 853 else 854 { 855 break; 856 } 857 858 } 859 while (num2 != 0); 860 861 count++; 862 863 int c = count; 864 865 S.Close(); 866 S = null; 867 if (flag1) 868 { 869 byte[] buffer3 = new byte[num3]; 870 Buffer.BlockCopy(buffer1, 0, buffer3, 0, num3); 871 buffer1 = buffer3; 872 } 873 874 UpdateControlFile(FileName, intFrom, (int)Length); 875 876 return buffer1; 877 } 878 catch (Exception e) 879 { 880 ExceptionActions ea = ExceptionActions.Throw; 881 if (this.ExceptionOccurrs != null) 882 { 883 Thread.Sleep(100); 884 //DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2); 885 //DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, (int)(Length - num3)); 886 DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, (int)Length); 887 888 ExceptionEventArgs eea = new ExceptionEventArgs(e, x); 889 ExceptionOccurrs(this, eea); 890 ea = eea.ExceptionAction; 891 } 892 893 if (ea == ExceptionActions.Throw) 894 { 895 if (!(e is WebException) && !(e is SecurityException)) 896 { 897 throw new WebException("net_webclient", e); 898 } 899 throw; 900 } 901 return null; 902 } 903 } 904 905 private void OnDataReceive(DownLoadEventArgs e) 906 { 907 //触发数据到达事件 908 DataReceive(this, e); 909 } 910 911 public byte[] UploadFile(string address, string fileName) 912 { 913 return this.UploadFile(address, "POST", fileName, "file"); 914 } 915 916 public string UploadFileEx(string address, string method, string fileName, string fieldName) 917 { 918 return Encoding.ASCII.GetString(UploadFile(address, method, fileName, fieldName)); 919 } 920 921 public byte[] UploadFile(string address, string method, string fileName, string fieldName) 922 { 923 byte[] buffer4; 924 FileStream stream1 = null; 925 try 926 { 927 fileName = Path.GetFullPath(fileName); 928 string text1 = "---------------------" + DateTime.Now.Ticks.ToString("x"); 929 930 string text2 = "application/octet-stream"; 931 932 stream1 = new FileStream(fileName, FileMode.Open, FileAccess.Read); 933 WebRequest request1 = WebRequest.Create(this.GetUri(address)); 934 request1.Credentials = this.m_credentials; 935 request1.ContentType = "multipart/form-data; boundary=" + text1; 936 937 request1.Method = method; 938 string[] textArray1 = new string[7] { "--", text1, "/r/nContent-Disposition: form-data; name=/"" + fieldName + "/"; filename=/"", Path.GetFileName(fileName), "/"/r/nContent-Type: ", text2, "/r/n/r/n" }; 939 string text3 = string.Concat(textArray1); 940 byte[] buffer1 = Encoding.UTF8.GetBytes(text3); 941 byte[] buffer2 = Encoding.ASCII.GetBytes("/r/n--" + text1 + "/r/n"); 942 long num1 = 0x7fffffffffffffff; 943 try 944 { 945 num1 = stream1.Length; 946 request1.ContentLength = (num1 + buffer1.Length) + buffer2.Length; 947 } 948 catch 949 { 950 } 951 byte[] buffer3 = new byte[Math.Min(0x2000, (int)num1)]; 952 using (Stream stream2 = request1.GetRequestStream()) 953 { 954 int num2; 955 stream2.Write(buffer1, 0, buffer1.Length); 956 do 957 { 958 num2 = stream1.Read(buffer3, 0, buffer3.Length); 959 if (num2 != 0) 960 { 961 stream2.Write(buffer3, 0, num2); 962 } 963 } 964 while (num2 != 0); 965 stream2.Write(buffer2, 0, buffer2.Length); 966 } 967 stream1.Close(); 968 stream1 = null; 969 WebResponse response1 = request1.GetResponse(); 970 971 buffer4 = this.ResponseAsBytes(response1); 972 } 973 catch (Exception exception1) 974 { 975 if (stream1 != null) 976 { 977 stream1.Close(); 978 stream1 = null; 979 } 980 if (!(exception1 is WebException) && !(exception1 is SecurityException)) 981 { 982 //throw new WebException(SR.GetString("net_webclient"), exception1); 983 throw new WebException("net_webclient", exception1); 984 } 985 throw; 986 } 987 return buffer4; 988 } 989 990 private byte[] ResponseAsBytes(WebResponse response) 991 { 992 int num2; 993 long num1 = response.ContentLength; 994 bool flag1 = false; 995 if (num1 == -1) 996 { 997 flag1 = true; 998 num1 = 0x10000; 999 } 1000 byte[] buffer1 = new byte[(int)num1]; 1001 Stream stream1 = response.GetResponseStream(); 1002 int num3 = 0; 1003 do 1004 { 1005 num2 = stream1.Read(buffer1, num3, ((int)num1) - num3); 1006 num3 += num2; 1007 if (flag1 && (num3 == num1)) 1008 { 1009 num1 += 0x10000; 1010 byte[] buffer2 = new byte[(int)num1]; 1011 Buffer.BlockCopy(buffer1, 0, buffer2, 0, num3); 1012 buffer1 = buffer2; 1013 } 1014 } 1015 while (num2 != 0); 1016 stream1.Close(); 1017 if (flag1) 1018 { 1019 byte[] buffer3 = new byte[num3]; 1020 Buffer.BlockCopy(buffer1, 0, buffer3, 0, num3); 1021 buffer1 = buffer3; 1022 } 1023 return buffer1; 1024 } 1025 1026 private NameValueCollection m_requestParameters; 1027 private Uri m_baseAddress; 1028 private ICredentials m_credentials = CredentialCache.DefaultCredentials; 1029 1030 public ICredentials Credentials 1031 { 1032 get 1033 { 1034 return this.m_credentials; 1035 } 1036 set 1037 { 1038 this.m_credentials = value; 1039 } 1040 } 1041 1042 public NameValueCollection QueryString 1043 { 1044 get 1045 { 1046 if (this.m_requestParameters == null) 1047 { 1048 this.m_requestParameters = new NameValueCollection(); 1049 } 1050 return this.m_requestParameters; 1051 } 1052 set 1053 { 1054 this.m_requestParameters = value; 1055 } 1056 } 1057 1058 public string BaseAddress 1059 { 1060 get 1061 { 1062 if (this.m_baseAddress != null) 1063 { 1064 return this.m_baseAddress.ToString(); 1065 } 1066 return string.Empty; 1067 } 1068 set 1069 { 1070 if ((value == null) || (value.Length == 0)) 1071 { 1072 this.m_baseAddress = null; 1073 } 1074 else 1075 { 1076 try 1077 { 1078 this.m_baseAddress = new Uri(value); 1079 } 1080 catch (Exception exception1) 1081 { 1082 throw new ArgumentException("value", exception1); 1083 } 1084 } 1085 } 1086 } 1087 1088 public Uri GetUri(string path) 1089 { 1090 Uri uri1; 1091 try 1092 { 1093 if (this.m_baseAddress != null) 1094 { 1095 uri1 = new Uri(this.m_baseAddress, path); 1096 } 1097 else 1098 { 1099 uri1 = new Uri(path); 1100 } 1101 if (this.m_requestParameters == null) 1102 { 1103 return uri1; 1104 } 1105 StringBuilder builder1 = new StringBuilder(); 1106 string text1 = string.Empty; 1107 for (int num1 = 0; num1 < this.m_requestParameters.Count; num1++) 1108 { 1109 builder1.Append(text1 + this.m_requestParameters.AllKeys[num1] + "=" + this.m_requestParameters[num1]); 1110 text1 = "&"; 1111 } 1112 UriBuilder builder2 = new UriBuilder(uri1); 1113 builder2.Query = builder1.ToString(); 1114 uri1 = builder2.Uri; 1115 } 1116 catch (UriFormatException) 1117 { 1118 uri1 = new Uri(Path.GetFullPath(path)); 1119 } 1120 return uri1; 1121 } 1122 1123 } 1124 1125 } 1126 1127 |