示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
            }
        }