private void Execute(ISender client, DoDownloadFileResponse message) { FileTransfer transfer; lock (_syncLock) { transfer = _activeFileTransfers.FirstOrDefault(t => t.Id == message.Id); } if (transfer == null) { // don't escape from download directory if (FileHelper.CheckPathForIllegalChars(message.Filename)) { // disconnect malicious client client.Disconnect(); return; } if (!Directory.Exists(_baseDownloadPath)) { Directory.CreateDirectory(_baseDownloadPath); } string downloadPath = Path.Combine(_baseDownloadPath, message.Filename); int i = 1; while (File.Exists(downloadPath)) { // rename file if it exists already var newFileName = string.Format("{0}({1}){2}", Path.GetFileNameWithoutExtension(downloadPath), i, Path.GetExtension(downloadPath)); downloadPath = Path.Combine(_baseDownloadPath, newFileName); i++; } transfer = new FileTransfer { Id = message.Id, Type = TransferType.Download, LocalPath = downloadPath, RemotePath = message.Filename, // TODO: Change to absolute path Size = message.MaxBlocks, // TODO: Change to real size TransferredSize = 0 }; lock (_syncLock) { _activeFileTransfers.Add(transfer); } } // TODO: change to += message.Block.Length transfer.TransferredSize = message.CurrentBlock + 1; if (!string.IsNullOrEmpty(message.CustomMessage)) { // client-side error transfer.Status = message.CustomMessage; OnFileTransferUpdated(transfer); return; } FileSplit destFile = new FileSplit(transfer.LocalPath); if (!destFile.AppendBlock(message.Block, message.CurrentBlock)) { // server-side error transfer.Status = destFile.LastError; OnFileTransferUpdated(transfer); return; } if (message.CurrentBlock + 1 == message.MaxBlocks) { transfer.Status = "Completed"; } else { decimal progress = Math.Round((decimal)((double)(message.CurrentBlock + 1) / (double)message.MaxBlocks * 100.0), 2); transfer.Status = $"Downloading...({progress}%)"; } OnFileTransferUpdated(transfer); }
public static void HandleDoDownloadFileResponse(Client client, DoDownloadFileResponse packet) { if (CanceledDownloads.ContainsKey(packet.ID) || string.IsNullOrEmpty(packet.Filename) || PausedDownloads.ContainsKey(packet.ID)) { return; } if (!Directory.Exists(client.Value.DownloadDirectory)) { Directory.CreateDirectory(client.Value.DownloadDirectory); } if (!Directory.Exists(Path.Combine(client.Value.DownloadDirectory, "temp"))) { Directory.CreateDirectory(Path.Combine(client.Value.DownloadDirectory, "temp")); } string metaFilePath = Path.Combine(client.Value.DownloadDirectory, "temp", packet.ID + ".meta"); string downloadPath = Path.Combine(client.Value.DownloadDirectory, packet.Filename); if (packet.CurrentBlock == 0 && File.Exists(downloadPath)) { for (int i = 1; i < 100; i++) { var newFileName = string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(downloadPath), i, Path.GetExtension(downloadPath)); if (File.Exists(Path.Combine(client.Value.DownloadDirectory, newFileName))) { continue; } downloadPath = Path.Combine(client.Value.DownloadDirectory, newFileName); RenamedFiles.Add(packet.ID, newFileName); break; } } else if (packet.CurrentBlock == 0 && Directory.Exists(downloadPath)) { for (int i = 1; i < 100; i++) { var newFileName = string.Format("{0} ({1})", downloadPath, i); if (Directory.Exists(Path.Combine(client.Value.DownloadDirectory, newFileName))) { continue; } downloadPath = Path.Combine(client.Value.DownloadDirectory, newFileName); RenamedFiles.Add(packet.ID, newFileName); break; } } else if (packet.CurrentBlock > 0 && (File.Exists(downloadPath) || Directory.Exists(downloadPath)) && RenamedFiles.ContainsKey(packet.ID)) { downloadPath = Path.Combine(client.Value.DownloadDirectory, RenamedFiles[packet.ID]); } // Handle crashed renamed files too if (packet.CurrentBlock > 0 && File.Exists(metaFilePath)) { var tmpMeta = new MetaFile(File.ReadAllBytes(metaFilePath)); if (tmpMeta.LocalPath != downloadPath && tmpMeta.LocalPath != "") { downloadPath = tmpMeta.LocalPath; } } if (client.Value == null || client.Value.FrmFm == null) { FrmMain.Instance.SetStatusByClient(client, "Download aborted, please keep the File Manager open."); new Packets.ServerPackets.DoDownloadFileCancel(packet.ID).Execute(client); return; } int index = client.Value.FrmFm.GetTransferIndex(packet.ID); if (index < 0) { return; } if (!string.IsNullOrEmpty(packet.CustomMessage)) { if (client.Value.FrmFm == null) // abort download when form is closed { return; } client.Value.FrmFm.UpdateTransferStatus(index, packet.CustomMessage, 0); return; } byte[] prevHash = new byte[16]; byte[] hashSample = new byte[FileSplit.MAX_BLOCK_SIZE]; if (File.Exists(downloadPath)) { using (var fs = new FileStream(downloadPath, FileMode.Open)) { fs.Seek(-FileSplit.MAX_BLOCK_SIZE, SeekOrigin.End); fs.Read(hashSample, 0, FileSplit.MAX_BLOCK_SIZE); } using (var md5 = MD5.Create()) prevHash = md5.ComputeHash(hashSample); } FileSplit destFile = new FileSplit(downloadPath); if (!destFile.AppendBlock(packet.Block, packet.CurrentBlock)) { if (client.Value == null || client.Value.FrmFm == null) { return; } client.Value.FrmFm.UpdateTransferStatus(index, destFile.LastError, 0); return; } byte[] curHash; hashSample = new byte[FileSplit.MAX_BLOCK_SIZE]; using (var fs = new FileStream(downloadPath, FileMode.Open)) { fs.Seek(-FileSplit.MAX_BLOCK_SIZE, SeekOrigin.End); fs.Read(hashSample, 0, FileSplit.MAX_BLOCK_SIZE); } using (var md5 = MD5.Create()) curHash = md5.ComputeHash(hashSample); decimal progress = Math.Round((decimal)((double)(packet.CurrentBlock + 1) / (double)packet.MaxBlocks * 100.0), 2); decimal speed; int timeLeft = 0; try { speed = Math.Round((decimal)(packet.CurrentBlock * FileSplit.MAX_BLOCK_SIZE) / (DateTime.Now - packet.StartTime).Seconds, 0); timeLeft = (int)(((FileSplit.MAX_BLOCK_SIZE * (packet.MaxBlocks - packet.CurrentBlock)) / 1000) / (speed / 1000)); } catch (DivideByZeroException) { speed = 0; } MetaFile metaFile; // Paused/crashed folder downloads require this if (File.Exists(metaFilePath)) { metaFile = new MetaFile(File.ReadAllBytes(metaFilePath)); metaFile.CurrentBlock++; metaFile.TransferId = packet.ID; metaFile.Progress = progress; metaFile.PrevHash = prevHash; metaFile.CurHash = curHash; metaFile.RemotePath = packet.RemotePath; metaFile.LocalPath = downloadPath; metaFile.Type = TransferType.Download; } else { metaFile = new MetaFile(packet.CurrentBlock + 1, packet.ID, progress, prevHash, curHash, packet.RemotePath, downloadPath, TransferType.Download); } metaFile.Save(metaFilePath); if (client.Value == null || client.Value.FrmFm == null) { return; } if (CanceledDownloads.ContainsKey(packet.ID)) { return; } client.Value.FrmFm.UpdateTransferStatus(index, string.Format("Downloading...({0}%)", progress), -1, TimeSpan.FromSeconds(timeLeft), speed); if ((packet.CurrentBlock + 1) == packet.MaxBlocks) { if (client.Value.FrmFm == null) { return; } try { File.Delete(metaFilePath); } catch { } RenamedFiles.Remove(packet.ID); if (packet.Type == ItemType.Directory) { client.Value.FrmFm.UpdateTransferStatus(index, "Unpacking directory", -1); var vDir = new VirtualDirectory().DeSerialize(downloadPath); if (File.Exists(downloadPath + ".bkp")) { File.Delete(downloadPath + ".bkp"); } File.Move(downloadPath, downloadPath + ".bkp"); try { vDir.SaveToDisk(Path.GetDirectoryName(downloadPath)); if (File.Exists(downloadPath + ".bkp")) { File.Delete(downloadPath + ".bkp"); } } catch { } } client.Value.FrmFm.UpdateTransferStatus(index, "Completed", 1); } }
public static void HandleDoDownloadFileResponse(Client client, DoDownloadFileResponse packet) { if (CanceledDownloads.ContainsKey(packet.ID) || string.IsNullOrEmpty(packet.Filename)) { return; } // don't escape from download directory if (packet.Filename.IndexOfAny(DISALLOWED_FILENAME_CHARS) >= 0 || Path.IsPathRooted(packet.Filename)) { // disconnect malicious client client.Disconnect(); return; } if (!Directory.Exists(client.Value.DownloadDirectory)) { Directory.CreateDirectory(client.Value.DownloadDirectory); } string downloadPath = Path.Combine(client.Value.DownloadDirectory, packet.Filename); if (packet.CurrentBlock == 0 && File.Exists(downloadPath)) { for (int i = 1; i < 100; i++) { var newFileName = string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(downloadPath), i, Path.GetExtension(downloadPath)); if (File.Exists(Path.Combine(client.Value.DownloadDirectory, newFileName))) { continue; } downloadPath = Path.Combine(client.Value.DownloadDirectory, newFileName); RenamedFiles.Add(packet.ID, newFileName); break; } } else if (packet.CurrentBlock > 0 && File.Exists(downloadPath) && RenamedFiles.ContainsKey(packet.ID)) { downloadPath = Path.Combine(client.Value.DownloadDirectory, RenamedFiles[packet.ID]); } if (client.Value == null || client.Value.FrmFm == null) { FrmMain.Instance.SetStatusByClient(client, "Download aborted, please keep the File Manager open."); new Packets.ServerPackets.DoDownloadFileCancel(packet.ID).Execute(client); return; } int index = client.Value.FrmFm.GetTransferIndex(packet.ID); if (index < 0) { return; } if (!string.IsNullOrEmpty(packet.CustomMessage)) { if (client.Value.FrmFm == null) // abort download when form is closed { return; } client.Value.FrmFm.UpdateTransferStatus(index, packet.CustomMessage, 0); return; } FileSplit destFile = new FileSplit(downloadPath); if (!destFile.AppendBlock(packet.Block, packet.CurrentBlock)) { if (client.Value == null || client.Value.FrmFm == null) { return; } client.Value.FrmFm.UpdateTransferStatus(index, destFile.LastError, 0); return; } decimal progress = Math.Round((decimal)((double)(packet.CurrentBlock + 1) / (double)packet.MaxBlocks * 100.0), 2); if (client.Value == null || client.Value.FrmFm == null) { return; } if (CanceledDownloads.ContainsKey(packet.ID)) { return; } client.Value.FrmFm.UpdateTransferStatus(index, string.Format("Downloading...({0}%)", progress), -1); if ((packet.CurrentBlock + 1) == packet.MaxBlocks) { if (client.Value.FrmFm == null) { return; } RenamedFiles.Remove(packet.ID); client.Value.FrmFm.UpdateTransferStatus(index, "Completed", 1); } }
public static void HandleDoDownloadFileResponse(Client client, DoDownloadFileResponse packet) { if (CanceledDownloads.ContainsKey(packet.ID) || string.IsNullOrEmpty(packet.Filename)) { return; } if (!Directory.Exists(client.Value.DownloadDirectory)) { Directory.CreateDirectory(client.Value.DownloadDirectory); } string downloadPath = Path.Combine(client.Value.DownloadDirectory, packet.Filename); if (packet.CurrentBlock == 0 && File.Exists(downloadPath)) { for (int i = 1; i < 100; i++) { var newFileName = string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(downloadPath), i, Path.GetExtension(downloadPath)); if (File.Exists(Path.Combine(client.Value.DownloadDirectory, newFileName))) { continue; } downloadPath = Path.Combine(client.Value.DownloadDirectory, newFileName); RenamedFiles.Add(packet.ID, newFileName); break; } } else if (packet.CurrentBlock > 0 && File.Exists(downloadPath) && RenamedFiles.ContainsKey(packet.ID)) { downloadPath = Path.Combine(client.Value.DownloadDirectory, RenamedFiles[packet.ID]); } if (client.Value == null || client.Value.FrmFm == null) { AnaForm.Instance.KurbanDurumuAyarla(client, "İndirme iptal edildi, Lütfen Dosya Yöneticisini Açık Tutunuz."); new DoDownloadFileCancel(packet.ID).Execute(client); return; } var index = client.Value.FrmFm.GetTransferIndex(packet.ID); if (index < 0) { return; } if (!string.IsNullOrEmpty(packet.CustomMessage)) { if (client.Value.FrmFm == null) { return; } client.Value.FrmFm.UpdateTransferStatus(index, packet.CustomMessage, 0); return; } var destFile = new FileSplit(downloadPath); if (!destFile.AppendBlock(packet.Block, packet.CurrentBlock)) { if (client.Value == null || client.Value.FrmFm == null) { return; } client.Value.FrmFm.UpdateTransferStatus(index, destFile.LastError, 0); return; } var progress = Math.Round((decimal)((packet.CurrentBlock + 1) / (double)packet.MaxBlocks * 100.0), 2); if (client.Value == null || client.Value.FrmFm == null) { return; } if (CanceledDownloads.ContainsKey(packet.ID)) { return; } client.Value.FrmFm.UpdateTransferStatus(index, string.Format("İndiriliyor...({0}%)", progress), -1); if ((packet.CurrentBlock + 1) == packet.MaxBlocks) { if (client.Value.FrmFm == null) { return; } RenamedFiles.Remove(packet.ID); client.Value.FrmFm.UpdateTransferStatus(index, "Tamamlandı", 1); } }
public static void doDownloadFileResponse(ClientMosaic client, DoDownloadFileResponse packet) { if (canceledDownloads.ContainsKey(packet.id) || string.IsNullOrEmpty(packet.fileName)) { return; } if (!Directory.Exists(client.value.downloadDirectory)) { Directory.CreateDirectory(client.value.downloadDirectory); } string downloadPath = Path.Combine(client.value.downloadDirectory, packet.fileName); if (packet.currentBlock == 0 && File.Exists(downloadPath)) { for (int i = 1; i < 100; i++) { var newFileName = string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(downloadPath), i, Path.GetExtension(downloadPath)); if (File.Exists(Path.Combine(client.value.downloadDirectory, newFileName))) { continue; } downloadPath = Path.Combine(client.value.downloadDirectory, newFileName); renamedFiles.Add(packet.id, newFileName); break; } } else if (packet.currentBlock > 0 && File.Exists(downloadPath) && renamedFiles.ContainsKey(packet.id)) { downloadPath = Path.Combine(client.value.downloadDirectory, renamedFiles[packet.id]); } if (client.value == null || client.value.frmFm == null) { //System.Windows.Forms.MessageBox.Show("l 140 - FMController"); //FrmMain.Instance.SetStatusByClient(client, "Download aborted, please keep the File Manager open."); new DoDownloadFileCancel(packet.id).Execute(client); return; } int index = client.value.frmFm.getTransferIndex(packet.id); if (index < 0) { return; } if (!string.IsNullOrEmpty(packet.customMessage)) { if (client.value.frmFm == null) // abort download when form is closed { return; } client.value.frmFm.updateTransferStatus(index, packet.customMessage, 0); return; } FileSplit destFile = new FileSplit(downloadPath); if (!destFile.AppendBlock(packet.block, packet.currentBlock)) { if (client.value == null || client.value.frmFm == null) { return; } client.value.frmFm.updateTransferStatus(index, destFile.LastError, 0); return; } decimal progress = Math.Round((decimal)((double)(packet.currentBlock + 1) / (double)packet.maxBlocks * 100.0), 2); if (client.value == null || client.value.frmFm == null) { return; } if (canceledDownloads.ContainsKey(packet.id)) { return; } client.value.frmFm.updateTransferStatus(index, string.Format("Downloading...({0}%)", progress), -1); if ((packet.currentBlock + 1) == packet.maxBlocks) { if (client.value.frmFm == null) { return; } renamedFiles.Remove(packet.id); client.value.frmFm.updateTransferStatus(index, "Completed", 1); } }