OSDN Git Service

na-get-lib,起動高速化機能追加時にインストール済みソフトのバージョン認識がされていないことがあったのを修正。
[applistation/AppliStation.git] / na-get-lib / NaGet.Net / Downloader.cs
index a38f76b..623e787 100644 (file)
@@ -1,7 +1,7 @@
 using System;\r
 using System.Net;\r
+using System.Net.Mime;\r
 using System.IO;\r
-using System.Collections;\r
 using System.Threading;\r
 using NaGet.SubCommands;\r
 \r
@@ -63,29 +63,38 @@ public enum DownloadEventType {
 /// </summary>\r
 public class Downloader : NaGetTask\r
 {\r
+       public IWebProxy proxy;\r
+       \r
        /// <summary>\r
-       /// ã\83\87ã\83\95ã\82©ã\83«ã\83\88ã\81§ä½¿ã\81\86ã\83\97ã\83­ã\82­ã\82·\r
+       /// ã\82¤ã\83\99ã\83³ã\83\88ã\83\8fã\83³ã\83\89ã\83©\r
        /// </summary>\r
-       public static IWebProxy DefaultProxy = WebRequest.GetSystemWebProxy();\r
+       public event EventHandler<DownloadEventArgs> DownloadEventRaised;\r
        \r
        /// <summary>\r
-       /// 通信に使うプロキシ\r
+       /// アクセスURL\r
        /// </summary>\r
-       public IWebProxy Proxy;\r
+       protected Uri url;\r
        \r
        /// <summary>\r
-       /// イベントハンドラ\r
+       /// 保存先\r
        /// </summary>\r
-       public event EventHandler<DownloadEventArgs> DownloadEventRaised;\r
-       \r
-       protected string url;\r
-       \r
        protected string filepath;\r
        \r
+       /// <summary>\r
+       /// リクエストオブジェクト\r
+       /// </summary>\r
        protected WebRequest request;\r
        \r
+       /// <summary>\r
+       /// レスポンスオブジェクト。応答がくるまではnullである。\r
+       /// </summary>\r
        protected WebResponse response;\r
        \r
+       /// <summary>\r
+       /// ダウンロード要求時のキャッシュレベル。デフォルトではキャッシュ無視\r
+       /// </summary>\r
+       public System.Net.Cache.RequestCacheLevel CacheLevel = System.Net.Cache.RequestCacheLevel.NoCacheNoStore;\r
+       \r
        private bool cancelCalled = false;\r
        \r
        private bool done = false;\r
@@ -96,6 +105,14 @@ public class Downloader : NaGetTask
        private string downloadedFileName = null;\r
        \r
        /// <summary>\r
+       /// ウェブアクセスに使うプロキシ\r
+       /// </summary>\r
+       public IWebProxy Proxy {\r
+               get { return proxy ?? NaGet.Env.WebProxy; }\r
+               set { proxy = value; }\r
+       }\r
+       \r
+       /// <summary>\r
        /// ダウンロード時にHTTPヘッダなどから取得した本来のファイル名\r
        /// </summary>\r
        public string DownloadedFileName {\r
@@ -112,7 +129,7 @@ public class Downloader : NaGetTask
        /// <param name="filepath">保存先ファイルパス</param>\r
        public void Download(string url, string filepath)\r
        {\r
-               this.url = url;\r
+               this.url = new Uri(url);\r
                this.filepath = filepath;\r
                \r
                try {\r
@@ -122,24 +139,35 @@ public class Downloader : NaGetTask
                }\r
        }\r
        \r
+       /// <summary>\r
+       /// 処理が終了したか否かのフラグ\r
+       /// </summary>\r
        public override bool Done {\r
                get { return done; }\r
        }\r
        \r
+       /// <summary>\r
+       /// 現在ダウンロード処理実行中であるかのフラグ\r
+       /// </summary>\r
        public override bool Running {\r
                get { return request != null && (!done); }\r
        }\r
 \r
+       /// <summary>\r
+       /// ダウンロード処理を実行する\r
+       /// </summary>\r
        public override void Run()\r
        {\r
                RaiseDownloadEvent(DownloadEventType.INITED, 0, -1);\r
                \r
                try {\r
                        request = WebRequest.Create(url);\r
-                       request.Proxy = (Proxy == null)? DefaultProxy : Proxy;    \r
-                       if (request is HttpWebRequest) {\r
-                               request.CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(\r
-                                       System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore);\r
+                       request.Proxy = this.Proxy;\r
+                       request.CachePolicy = new System.Net.Cache.RequestCachePolicy(CacheLevel);\r
+                       \r
+                       HttpWebRequest httpRequest = request as HttpWebRequest;\r
+                       if (httpRequest != null) {\r
+                               httpRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;  \r
                        }\r
                        \r
                        if (cancelCalled) {\r
@@ -198,8 +226,6 @@ public class Downloader : NaGetTask
                                                while ((size = stream.Read(data,0,data.Length)) > 0) {\r
                                                        fs.Write(data, 0, size);\r
                                                        \r
-                                                       bool hoge = cancelCalled;\r
-                                                       \r
                                                        if (cancelCalled) {\r
                                                                throw new NaGetTaskCanceledException(string.Empty);\r
                                                        }\r
@@ -225,6 +251,18 @@ public class Downloader : NaGetTask
                                        }\r
                                }\r
                        }\r
+                       \r
+                       // 更新日を補完\r
+                       if (File.Exists(filepath)) {\r
+                               HttpWebResponse httpResponse = response as HttpWebResponse;\r
+                               FtpWebResponse  ftpResponse      = response as FtpWebResponse;\r
+                               \r
+                               if (httpResponse != null) {\r
+                                       File.SetLastWriteTime(filepath, httpResponse.LastModified);\r
+                               } else if (ftpResponse != null) {\r
+                                       File.SetLastWriteTime(filepath, ftpResponse.LastModified);\r
+                               }\r
+                       }\r
                } finally {\r
                        if (response != null) {\r
                                response.Close();\r
@@ -247,19 +285,19 @@ public class Downloader : NaGetTask
                                case DownloadEventType.STARTED:\r
                                case DownloadEventType.DOWNLOADING:\r
                                case DownloadEventType.COMPLETED:\r
-                                       try {\r
+                                       if (e.TaskProgressPercent >= 0) {\r
                                                e.TaskMessage = string.Format("{0} bytes ({1} %)", e.DownloadSize, (int) e.TaskProgressPercent);\r
-                                       } catch (DivideByZeroException) {\r
+                                       } else {\r
                                                e.TaskMessage = string.Format("{0} bytes", e.DownloadSize);\r
                                        }\r
                                        \r
                                        \r
                                        if (stopwatch != null && stopwatch.IsRunning && stopwatch.ElapsedMilliseconds > 3000) {\r
                                                long bpers = e.DownloadSize * 1000 / stopwatch.ElapsedMilliseconds;\r
-                                               try {\r
+                                               if ((e.TaskProgressPercent >= 0) && (bpers > 0)) {\r
                                                        TimeSpan rest = TimeSpan.FromSeconds((max - e.DownloadSize) / bpers);\r
                                                        e.TaskMessage += string.Format(" 推定残り時間:{0} ({1}/s)", rest, NaGet.Utils.FormatSize(bpers));\r
-                                               } catch {\r
+                                               } else {\r
                                                        e.TaskMessage += string.Format(" ({0}/s)", NaGet.Utils.FormatSize(bpers));\r
                                                }\r
                                        }\r
@@ -271,10 +309,17 @@ public class Downloader : NaGetTask
                }\r
        }\r
        \r
+       /// <summary>\r
+       /// キャンセル可能かを返す\r
+       /// </summary>\r
        public override bool Cancelable {\r
                get { return !(this.Done || cancelCalled); }\r
        }\r
        \r
+       /// <summary>\r
+       /// ダウンロード処理をキャンセルする\r
+       /// </summary>\r
+       /// <returns>キャンセルに成功したときtrue</returns>\r
        public override bool Cancel()\r
        {\r
                if (this.Done || cancelCalled) {\r
@@ -294,27 +339,27 @@ public class Downloader : NaGetTask
        /// <summary>\r
        /// Webレスポンスからダウンロードしたファイルの名前を取得\r
        /// </summary>\r
-       /// <param name="response"></param>\r
-       /// <returns></returns>\r
-       private string getFileNameFromWebResponse(WebResponse response)\r
+       /// <remarks>Content-Dispositionヘッダから取得あるいはURLの末尾から推定します</remarks>\r
+       /// <param name="response">レスポンスオブジェクト</param>\r
+       /// <returns>取得したファイル名</returns>\r
+       private static string getFileNameFromWebResponse(WebResponse response)\r
        {\r
-               if (response is HttpWebResponse) {\r
-                       string contentDisposition = ((HttpWebResponse) response).Headers["Content-Disposition"];\r
+               HttpWebResponse httpresp = response as HttpWebResponse;\r
+               if (httpresp != null) {\r
+                       string contentDisposition = httpresp.Headers["Content-Disposition"];\r
                        \r
-                       // TODO check license for http://www.atmarkit.co.jp/fdotnet/dotnettips/618downnoname/downnoname.html\r
                        if (! string.IsNullOrEmpty(contentDisposition)) {\r
-                               System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(\r
-                                       @"filename\s*=\s*(?:""(?<filename>[^""]*)""|(?<filename>[^;]*))",\r
-                                       System.Text.RegularExpressions.RegexOptions.IgnoreCase);\r
-                               \r
-                               System.Text.RegularExpressions.Match m = re.Match(contentDisposition);\r
-                               if (m.Success) {\r
-                                       return m.Groups["filename"].Value;\r
+                               try {\r
+                                       ContentDisposition parser = new ContentDisposition(contentDisposition);\r
+                                       if (! string.IsNullOrEmpty(parser.FileName)) {\r
+                                               return parser.FileName;\r
+                                       }\r
+                               } catch (FormatException) {\r
                                }\r
                        }\r
                }\r
                \r
-               return NaGet.Utils.Url2filename(response.ResponseUri.ToString());\r
+               return NaGet.Utils.Url2filename(response.ResponseUri);\r
        }\r
 }\r
 \r