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
/// </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
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
/// <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
}\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
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
}\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
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
}\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
/// <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