public async Task <bool> Login(CancellationToken ct = default(CancellationToken)) { Config.Log.LogOut("\t[Login]"); if (string.IsNullOrEmpty(Config.refresh_token)) { Thread t = new Thread(new ThreadStart(() => { Authkey = new FormLogin().Login(ct); })); t.SetApartmentState(System.Threading.ApartmentState.STA); t.IsBackground = true; t.Start(); while (t.IsAlive) { await Task.Delay(1000).ConfigureAwait(false); } if (Authkey != null && !string.IsNullOrEmpty(Authkey.access_token)) { key_timer = DateTime.Now; DriveData.RemoveCache(); return(true); } return(false); } else { return(await Refresh(ct).ConfigureAwait(false)); } }
static FileMetadata_Info[] FindItems(string[] path_str, bool recursive = false, FileMetadata_Info root = null) { List <FileMetadata_Info> ret = new List <FileMetadata_Info>(); if (root == null) { root = DriveData.AmazonDriveTree[DriveData.AmazonDriveRootID].info; } if (!(path_str?.Length > 0)) { ret.Add(root); return(ret.ToArray()); } while (path_str.Length > 0 && string.IsNullOrEmpty(path_str.First())) { path_str = path_str.Skip(1).ToArray(); } if (path_str.Length == 0) { ret.Add(root); return(ret.ToArray()); } var children = DriveData.AmazonDriveTree[root.id].children.Select(x => x.Value); foreach (var c in children) { if (c.DisplayName == path_str[0] || ((path_str[0].Contains('*') || path_str[0].Contains('?')) && Regex.IsMatch(c.DisplayName, Regex.Escape(path_str[0]).Replace("\\*", ".*").Replace("\\?", ".")))) { if (c.info.kind == "FOLDER") { ret.AddRange(FindItems((recursive && path_str[0] == "*") ? path_str : path_str.Skip(1).ToArray(), recursive, c.info)); } else { if (path_str[0] == c.DisplayName || (((path_str[0].Contains('*') || path_str[0].Contains('?')) && Regex.IsMatch(c.DisplayName, Regex.Escape(path_str[0]).Replace("\\*", ".*").Replace("\\?", "."))))) { ret.Add(c.info); } } } } if (recursive) { ret.Sort((x, y) => (DriveData.GetFullPathfromId(x.id)).CompareTo(DriveData.GetFullPathfromId(y.id))); return(ret.ToArray()); } else { ret.Sort((x, y) => x.name.CompareTo(y.name)); return(ret.ToArray()); } }
private void listBox_remote_Format(object sender, ListControlConvertEventArgs e) { e.Value = DriveData.GetFullPathfromId((e.ListItem as FileMetadata_Info).id); }
private void button1_Click(object sender, EventArgs e) { if (SelectedRemoteFiles == null) { return; } List <MatchItem> RemoteOnly = new List <MatchItem>(); List <MatchItem> LocalOnly = new List <MatchItem>(); List <MatchItem> BothAndMatch = new List <MatchItem>(); List <MatchItem> BothAndUnmatch = new List <MatchItem>(); Dictionary <string, LocalItemInfo[]> LocalDup = new Dictionary <string, LocalItemInfo[]>(); Dictionary <string, RemoteItemInfo[]> RemoteDup = new Dictionary <string, RemoteItemInfo[]>(); var synchronizationContext = SynchronizationContext.Current; bool TreeFlag = radioButton_Tree.Checked; bool FilenameFlag = radioButton_filename.Checked; bool MD5Flag = radioButton_MD5.Checked; var job = JobControler.CreateNewJob(JobControler.JobClass.Normal); job.DisplayName = "Match"; job.ProgressStr = "wait for run"; runningJob = job; bool done = false; JobControler.Run(job, (j) => { job.ProgressStr = "running..."; job.Progress = -1; synchronizationContext.Post((o) => { button_start.Enabled = false; }, null); var remote = SelectedRemoteFiles.Select(x => new RemoteItemInfo(x, DriveData.GetFullPathfromId(x.id), null)).ToArray(); var remotebasepath = GetBasePath(remote.Select(x => x.path)); if (TreeFlag) { remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, x.path.Substring(remotebasepath.Length))).ToArray(); } if (FilenameFlag) { remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, DriveData.AmazonDriveTree[x.info.id].DisplayName)).ToArray(); } if (MD5Flag) { remote = remote.Select(x => new RemoteItemInfo(x.info, x.path, x.info.contentProperties?.md5)).ToArray(); } var localpath = listBox_local.Items.Cast <string>(); var localbasepath = GetBasePath(localpath); var len = localpath.Count(); int i = 0; foreach (var ritem in remote.GroupBy(x => x.name).Where(g => g.Count() > 1)) { RemoteDup[ritem.Key] = ritem.ToArray(); } var local = ((radioButton_MD5.Checked) ? (localpath.Select(x => { byte[] md5 = null; ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x)); using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider()) using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read)) { md5 = md5calc.ComputeHash(hfile); var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", ""); return(new LocalItemInfo(x, MD5, hfile.Length, MD5)); } })) : (radioButton_Tree.Checked) ? localpath.Select(x => { if (checkBox_MD5.Checked) { byte[] md5 = null; ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x)); using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider()) using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read)) { md5 = md5calc.ComputeHash(hfile); var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", ""); return(new LocalItemInfo(x, x.Substring(localbasepath.Length).Replace('\\', '/'), hfile.Length, MD5)); } } else { ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} Check file ...{2}", i, len, x)); return(new LocalItemInfo(x, x.Substring(localbasepath.Length).Replace('\\', '/'), new FileInfo(x).Length, null)); } }) : localpath.Select(x => { if (checkBox_MD5.Checked) { byte[] md5 = null; ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} Check file MD5...{2}", i, len, x)); using (var md5calc = new System.Security.Cryptography.MD5CryptoServiceProvider()) using (var hfile = File.Open(x, FileMode.Open, FileAccess.Read, FileShare.Read)) { md5 = md5calc.ComputeHash(hfile); var MD5 = BitConverter.ToString(md5).ToLower().Replace("-", ""); return(new LocalItemInfo(x, Path.GetFileName(x), hfile.Length, MD5)); } } else { ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} Check file ...{2}", i, len, x)); return(new LocalItemInfo(x, Path.GetFileName(x), new FileInfo(x).Length, null)); } })) .GroupBy(x => x.name).ToArray(); i = 0; foreach (var litem in local) { job.ct.ThrowIfCancellationRequested(); var matchitem = remote.Where(x => x.name == litem.FirstOrDefault()?.name).ToArray(); if (litem.Count() > 1) { LocalDup[litem.Key] = litem.ToArray(); } if (matchitem.Length > 0) { List <RemoteItemInfo> RemoteMatched = new List <RemoteItemInfo>(); List <LocalItemInfo> LocalUnMatched = new List <LocalItemInfo>(); // match test foreach (var item in litem) { ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} {2}", i, len, item.path)); List <RemoteItemInfo> Matched = new List <RemoteItemInfo>(); foreach (var ritem in matchitem) { if (item.size == ritem.info.contentProperties?.size) { if (item.MD5 == null || item.MD5 == ritem.info.contentProperties?.md5) { Matched.Add(ritem); } } } if (Matched.Count() == 0) { LocalUnMatched.Add(item); } BothAndMatch.AddRange(Matched.Select(x => new MatchItem(item, x))); RemoteMatched.AddRange(Matched); } var RemoteUnMatched = matchitem.Except(RemoteMatched); if (RemoteUnMatched.Count() < LocalUnMatched.Count()) { BothAndUnmatch.AddRange(RemoteUnMatched.Concat(RemoteMatched).Zip(LocalUnMatched, (r, l) => new MatchItem(l, r))); } else if (RemoteUnMatched.Count() > LocalUnMatched.Count()) { BothAndUnmatch.AddRange(LocalUnMatched.Concat(litem).Zip(RemoteUnMatched, (l, r) => new MatchItem(l, r))); } else { if (RemoteUnMatched.Count() > 0) { BothAndUnmatch.AddRange(LocalUnMatched.Zip(RemoteUnMatched, (l, r) => new MatchItem(l, r))); } } } else { //nomatch foreach (var item in litem) { ++i; synchronizationContext.Post((o) => { if (runningJob?.ct.IsCancellationRequested ?? true) { return; } label_info.Text = o as string; }, string.Format("{0}/{1} {2}", i, len, item.path)); LocalOnly.Add(new MatchItem(item, null)); } } } RemoteOnly.AddRange(remote.Select(x => x.info) .Except(BothAndMatch.Select(x => x.remote.info)) .Except(BothAndUnmatch.Select(x => x.remote.info)) .Select(x => remote.Where(y => y.info == x).FirstOrDefault()) .Select(x => new MatchItem(null, x))); done = true; job.Progress = 1; job.ProgressStr = "done."; }); var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: job); afterjob.DisplayName = "clean up"; afterjob.DoAlways = true; JobControler.Run(afterjob, (j) => { afterjob.ProgressStr = "done."; afterjob.Progress = 1; runningJob = null; synchronizationContext.Post((o) => { label_info.Text = ""; button_start.Enabled = true; if (done) { var result = new FormMatchResult(); result.RemoteOnly = RemoteOnly; result.LocalOnly = LocalOnly; result.Unmatch = BothAndUnmatch; result.Match = BothAndMatch; result.RemoteDup = RemoteDup; result.LocalDup = LocalDup; result.Show(); } }, null); }); }
static int Download(string[] targetArgs, string[] paramArgs, bool index_mode = false) { var masterjob = JobControler.CreateNewJob(JobControler.JobClass.ControlMaster); masterjob.DisplayName = "Download"; var ct = masterjob.ct; JobControler.Run(masterjob, (j) => { string remotepath = null; string localpath = null; string indexpath = null; string ignorespath = null; FileMetadata_Info[] target = null; if (index_mode) { if (targetArgs.Length > 4) { ignorespath = targetArgs[4]; } if (targetArgs.Length > 3) { localpath = targetArgs[3]; } if (targetArgs.Length > 2) { remotepath = targetArgs[2]; remotepath = remotepath.Replace('\\', '/'); } if (targetArgs.Length > 1) { indexpath = targetArgs[1]; } } else { if (targetArgs.Length > 3) { ignorespath = targetArgs[3]; } if (targetArgs.Length > 2) { localpath = targetArgs[2]; } if (targetArgs.Length > 1) { remotepath = targetArgs[1]; remotepath = remotepath.Replace('\\', '/'); } } if (string.IsNullOrEmpty(remotepath)) { masterjob.Result = 0; return; } bool autodecrypt = true; foreach (var p in paramArgs) { switch (p) { case "nodecrypt": Console.Error.WriteLine("(--nodecrypt: disable auto decrypt)"); autodecrypt = false; break; } } AmazonDriveControl.autodecrypt = autodecrypt; AmazonDriveControl.indexpath = indexpath; string itembasepath; try { var loginjob = Login(); var initjob = AmazonDriveControl.InitAlltree(loginjob); initjob.Wait(ct: ct); target = FindItems(remotepath?.Split('/')); var target2 = target.SelectMany(x => DriveData.GetAllChildrenfromId(x.id)); itembasepath = FormMatch.GetBasePath(target.Select(x => DriveData.GetFullPathfromId(x.id)).Distinct()); target = target2.Where(x => x.kind == "FILE").ToArray(); if (target.Length < 1) { masterjob.Result = 2; return; } } catch (OperationCanceledException) { masterjob.Result = -1; return; } catch (Exception ex) { Console.Error.WriteLine("error: " + ex.ToString()); masterjob.Result = 1; return; } if (ignorespath != null) { var targetdict = new ConcurrentDictionary <string, FileMetadata_Info>(); Parallel.ForEach(target, item => { targetdict[DriveData.GetFullPathfromId(item.id)] = item; }); Console.WriteLine("ignore list loading..."); using (var file = new FileStream(ignorespath, FileMode.Open)) using (var sr = new StreamReader(file)) { while (!sr.EndOfStream) { var line = sr.ReadLine().Split('\t'); FileMetadata_Info o; if (line.Length > 1) { if (targetdict.TryGetValue(line[0], out o)) { if (o.contentProperties?.md5 == line[1]) { if (targetdict.TryRemove(line[0], out o)) { Console.WriteLine(line[0]); } } } } else { if (targetdict.TryRemove(line[0], out o)) { Console.WriteLine(line[0]); } } } } target = targetdict.Values.ToArray(); Console.WriteLine("remain target: " + target.Length); if (target.Length < 1) { masterjob.Result = 2; return; } } bool SelectFullpath = false; if (String.IsNullOrEmpty(localpath)) { Thread t = new Thread(new ThreadStart(() => { if (target.Length > 1) { using (var save = new FolderBrowserDialog()) { save.Description = "Select Save Folder for Download Items"; if (save.ShowDialog() != DialogResult.OK) { return; } localpath = save.SelectedPath; } } else { using (var save = new SaveFileDialog()) { var filename = DriveData.AmazonDriveTree[target[0].id].DisplayName; save.FileName = filename; if (save.ShowDialog() != DialogResult.OK) { return; } localpath = save.FileName; SelectFullpath = true; } } })); t.SetApartmentState(System.Threading.ApartmentState.STA); t.Start(); t.Join(); if (localpath == null) { masterjob.Result = 0; return; } } try { Console.Error.WriteLine("remote:" + remotepath); Console.Error.WriteLine("local:" + localpath); if (indexpath != null) { Console.Error.WriteLine("index:" + indexpath); } if (target.Length == 1) { var filename = DriveData.AmazonDriveTree[target[0].id].DisplayName; if (!SelectFullpath) { localpath = Path.Combine(localpath, filename); } } if (target.Length > 1 && Path.GetFileName(localpath) != "") { localpath += "\\"; } ConsoleJobDisp.Run(); var jobs = AmazonDriveControl.downloadItems(target, localpath, masterjob); int errorcount = 0; Task.WaitAll(jobs.Select(x => x.WaitTask(ct: ct)).ToArray()); foreach (var j2 in jobs) { if (j2.IsError) { errorcount++; } } masterjob.Result = (errorcount == 0) ? 0 : errorcount + 10; } catch (OperationCanceledException) { masterjob.Result = -1; } catch (Exception ex) { Console.Error.WriteLine("error: " + ex.ToString()); masterjob.Result = 1; } }); try { masterjob.Wait(ct: ct); } catch (OperationCanceledException) { } Config.IsClosing = true; Console.Out.Flush(); return((masterjob.Result as int?) ?? -1); }
static int ListItems(string[] targetArgs, string[] paramArgs) { var job = JobControler.CreateNewJob(JobControler.JobClass.ControlMaster); job.DisplayName = "ListItem"; JobControler.Run(job, (j) => { string remotepath = null; FileMetadata_Info[] target = null; if (targetArgs.Length > 1) { remotepath = targetArgs[1]; remotepath = remotepath.Replace('\\', '/'); } bool recursive = false; bool showmd5 = false; bool nodecrypt = false; foreach (var p in paramArgs) { switch (p) { case "recursive": Console.Error.WriteLine("(--recursive: recursive mode)"); recursive = true; break; case "md5": Console.Error.WriteLine("(--md5: show MD5 hash)"); showmd5 = true; break; case "nodecrypt": Console.Error.WriteLine("(--nodecrypt: disable auto decrypt)"); nodecrypt = true; break; } } try { var loginjob = Login(); var initjob = AmazonDriveControl.InitAlltree(loginjob); initjob.Wait(ct: job.ct); target = FindItems(remotepath?.Split('/'), recursive: recursive); if (target.Length < 1) { job.Result = 2; return; } Console.Error.WriteLine("Found : " + target.Length); foreach (var item in target) { string detail = ""; if (showmd5) { detail = "\t" + item.contentProperties?.md5; } if (recursive) { Console.WriteLine(DriveData.GetFullPathfromId(item.id, nodecrypt) + detail); } else { Console.WriteLine(((nodecrypt) ? item.name : DriveData.AmazonDriveTree[item.id].DisplayName) + ((item.kind == "FOLDER") ? "/" : "") + detail); } } job.Result = 0; } catch (OperationCanceledException) { job.Result = -1; } catch (Exception ex) { Console.Error.WriteLine("error: " + ex.ToString()); job.Result = 1; } }); try { job.Wait(ct: job.ct); } catch (OperationCanceledException) { } Config.IsClosing = true; Console.Out.Flush(); return((job.Result as int?) ?? -1); }
private void ProcessCryption() { if (IsEncrypted == CryptMethods.Unknown) { if (info?.name?.StartsWith(Config.CarotDAV_CryptNameHeader) ?? false) { IsEncrypted = CryptMethods.Method2_CBC_CarotDAV; } else if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$")) { IsEncrypted = CryptMethods.Method1_CTR; _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name)); return; } else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$")) { IsEncrypted = CryptMethods.Method1_CTR; var decodename = DriveData.DecryptFilename(info); if (decodename != null) { IsEncrypted = CryptMethods.Method1_CTR; _DisplayName = Path.GetFileNameWithoutExtension(decodename); return; } _DisplayName = info?.name; CryptError = true; } else { IsEncrypted = CryptMethods.Method0_Plain; } } switch (IsEncrypted) { case CryptMethods.Method0_Plain: _DisplayName = info?.name; break; case CryptMethods.Method1_CTR: if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$")) { _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name)); CryptError = false; } else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$")) { var decodename = DriveData.DecryptFilename(info); if (decodename != null) { _DisplayName = Path.GetFileNameWithoutExtension(decodename); CryptError = false; } else { _DisplayName = info?.name; CryptError = true; } } else { IsEncrypted = CryptMethods.Method0_Plain; _DisplayName = info?.name; } break; case CryptMethods.Method2_CBC_CarotDAV: { var decodename = CryptCarotDAV.DecryptFilename(info?.name); if (decodename != null) { _DisplayName = decodename; CryptError = false; } else { _DisplayName = info?.name; CryptError = true; } } break; } }
private void button_Start_Click(object sender, EventArgs e) { if (SelectedRemoteFiles == null) { return; } button_Start.Enabled = false; var synchronizationContext = SynchronizationContext.Current; var masterjob = JobControler.CreateNewJob(JobControler.JobClass.Normal); masterjob.DisplayName = "Download test"; masterjob.ProgressStr = "wait for download"; runningjob = masterjob; var joblist = new ConcurrentBag <JobControler.Job>(); Parallel.ForEach(SelectedRemoteFiles, (item) => { var job = JobControler.CreateNewJob(JobControler.JobClass.Download, depends: masterjob); job.WeekDepend = true; job.DisplayName = DriveData.GetFullPathfromId(item.id); job.ProgressStr = "Wait for download"; joblist.Add(job); var ct = CancellationTokenSource.CreateLinkedTokenSource(masterjob.ct, job.ct).Token; JobControler.Run(job, (j) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "download..."; }, null); (j as JobControler.Job).ProgressStr = "download..."; var retry = 5; while (--retry > 0) { ct.ThrowIfCancellationRequested(); try { long length = item.contentProperties.size ?? 0; using (var ret = new AmazonDriveBaseStream(DriveData.Drive, item, autodecrypt: false, parentJob: (j as JobControler.Job))) using (var f = new PositionStream(ret, length)) { f.PosChangeEvent += (src, evnt) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var eo = o as PositionChangeEventArgs; var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = eo.Log; }, evnt); (j as JobControler.Job).ProgressStr = evnt.Log; (j as JobControler.Job).Progress = (double)evnt.Position / evnt.Length; }; f.CopyTo(new NullStream()); } synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Done"; }, null); (j as JobControler.Job).ProgressStr = "Done."; (j as JobControler.Job).Progress = 1; break; } catch (OperationCanceledException) { throw; } catch (Exception ex) { Config.Log.LogOut("Download : Error " + ex.Message); continue; } } if (retry == 0) { // failed synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Failed"; }, null); (j as JobControler.Job).ProgressStr = "Failed"; (j as JobControler.Job).Progress = double.NaN; (j as JobControler.Job).IsError = true; } }); }); JobControler.Run(masterjob, (j) => { masterjob.ProgressStr = "running..."; masterjob.Progress = -1; var ct = (j as JobControler.Job).ct; Task.WaitAll(joblist.Select(x => x.WaitTask(ct: ct)).ToArray()); masterjob.Progress = 1; masterjob.ProgressStr = "done."; }); var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: masterjob); afterjob.DisplayName = "clean up"; afterjob.DoAlways = true; JobControler.Run(afterjob, (j) => { afterjob.ProgressStr = "done."; afterjob.Progress = 1; runningjob = null; synchronizationContext.Post((o) => { button_Start.Enabled = true; }, null); }); }
public async Task <Stream> downloadFile(FileMetadata_Info target, long?from = null, long?to = null, string enckey = null, bool autodecrypt = true, CancellationToken ct = default(CancellationToken)) { string id = target.id; string filename = target.name; CryptMethods Encrypted = CryptMethods.Method0_Plain; if (enckey != null) { Encrypted = CryptMethods.Method1_CTR; } else { if (filename.StartsWith(Config.CarotDAV_CryptNameHeader)) { Encrypted = CryptMethods.Method2_CBC_CarotDAV; enckey = ""; } else if (Regex.IsMatch(filename, ".*?\\.[a-z0-9]{8}\\.enc$")) { Encrypted = CryptMethods.Method1_CTR; enckey = Path.GetFileNameWithoutExtension(filename); } else if (Regex.IsMatch(filename, "^[\u2800-\u28ff]+$")) { enckey = DriveData.DecryptFilename(target); if (enckey != null) { Encrypted = CryptMethods.Method1_CTR; } } if (enckey == null) { Encrypted = CryptMethods.Method0_Plain; } } if (!autodecrypt) { Encrypted = CryptMethods.Method0_Plain; } Config.Log.LogOut("\t[downloadFile] " + id); string error_str = ""; var client = new HttpClient(); client.Timeout = TimeSpan.FromDays(1); try { long?fix_from = from, fix_to = to; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Authkey.access_token); if (from != null || to != null) { if (Encrypted == CryptMethods.Method2_CBC_CarotDAV) { if (fix_from != null) { // ひとつ前のブロックから要求する fix_from -= CryptCarotDAV.BlockSizeByte; if (fix_from < CryptCarotDAV.BlockSizeByte) { // 先頭ブロックを取得するときはファイルの先頭から fix_from = 0; } else { // ブロックにアライメントを合わせる fix_from -= ((fix_from - 1) % CryptCarotDAV.BlockSizeByte + 1); // 途中のブロックを要求された場合は、ヘッダをスキップ fix_from += CryptCarotDAV.CryptHeaderByte; } } if (fix_to != null) { if (fix_to >= target.OrignalLength) { // 末尾まで読み込むときは、ハッシュチェックのために最後まで読み込む fix_to = null; } else { // オリジナルの位置を、暗号化済みの位置に変更 fix_to += CryptCarotDAV.CryptHeaderByte; } } if (fix_from != null || fix_to != null) { client.DefaultRequestHeaders.Range = new RangeHeaderValue(fix_from, fix_to); } } else { client.DefaultRequestHeaders.Range = new RangeHeaderValue(from, to); } } string url = Config.contentUrl + "nodes/" + id + "/content?download=false"; var response = await client.GetAsync( url, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false); response.EnsureSuccessStatusCode(); if (Encrypted == CryptMethods.Method1_CTR) { return(new CryptCTR.AES256CTR_CryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct), enckey, from ?? 0)); } else if (Encrypted == CryptMethods.Method2_CBC_CarotDAV) { return(new CryptCarotDAV.CryptCarotDAV_DecryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct), from ?? 0, fix_from ?? 0, target.contentProperties?.size ?? -1 )); } else { return(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct)); } } catch (HttpRequestException ex) { error_str = ex.Message; Config.Log.LogOut("\t[downloadFile] " + error_str); throw; } catch (OperationCanceledException) { throw; } catch (Exception ex) { error_str = ex.ToString(); Config.Log.LogOut("\t[downloadFile] " + error_str); throw; } throw new SystemException("fileDownload failed. " + error_str); }