Exemplo n.º 1
0
        /// <summary>
        /// Renames a file on the FTP server
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public async Task RenameAsync(string from, string to)
        {
            EnsureLoggedIn();
            LoggerHelper.Debug($"[FtpClient] Renaming from {from}, to {to}");
            var renameFromResponse = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.RNFR,
                Data       = from
            });

            if (renameFromResponse.FtpStatusCode != FtpStatusCode.FileCommandPending)
            {
                throw new FtpException(renameFromResponse.ResponseMessage);
            }

            var renameToResponse = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.RNTO,
                Data       = to
            });

            if (renameToResponse.FtpStatusCode != FtpStatusCode.FileActionOK && renameToResponse.FtpStatusCode != FtpStatusCode.ClosingData)
            {
                throw new FtpException(renameFromResponse.ResponseMessage);
            }
        }
Exemplo n.º 2
0
 public void Dispose()
 {
     LoggerHelper.Debug("Disposing of FtpClient");
     Task.WaitAny(LogOutAsync());
     ControlStream?.Dispose();
     dataSocketSemaphore?.Dispose();
 }
Exemplo n.º 3
0
        /// <summary>
        /// Informs the FTP server of the client being used
        /// </summary>
        /// <param name="clientName"></param>
        /// <returns></returns>
        public async Task <FtpResponse> SetClientName(string clientName)
        {
            EnsureLoggedIn();
            LoggerHelper.Debug($"[FtpClient] Setting client name to {clientName}");

            return(await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.CLNT,
                Data = clientName
            }));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Throws an exception if the server response is not one of the given acceptable codes
        /// </summary>
        /// <param name="response"></param>
        /// <param name="codes"></param>
        /// <returns></returns>
        private async Task BailIfResponseNotAsync(FtpResponse response, params FtpStatusCode[] codes)
        {
            if (codes.Any(x => x == response.FtpStatusCode))
            {
                return;
            }

            LoggerHelper.Debug($"Bailing due to response codes being {response.FtpStatusCode}, which is not one of: [{string.Join(",", codes)}]");

            await LogOutAsync();

            throw new FtpException(response.ResponseMessage);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Lists all directories in the current working directory
 /// </summary>
 /// <returns></returns>
 public async Task <IEnumerable <FtpNodeInformation> > ListDirectoriesAsync()
 {
     try
     {
         EnsureLoggedIn();
         LoggerHelper.Debug($"[FtpClient] Listing directories in {WorkingDirectory}");
         return(await directoryProvider.ListDirectoriesAsync());
     }
     finally
     {
         await ControlStream.GetResponseAsync();
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Provides a stream which can be written to
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task <Stream> OpenFileWriteStreamAsync(string fileName)
        {
            string filePath = WorkingDirectory.CombineAsUriWith(fileName);

            LoggerHelper.Debug($"[FtpClient] Opening file read stream for {filePath}");
            var segments = filePath.Split('/')
                           .Where(x => !x.IsNullOrWhiteSpace())
                           .ToList();

            await CreateDirectoryStructureRecursively(segments.Take(segments.Count - 1).ToArray(), filePath.StartsWith("/"));

            return(new FtpDataStream(await OpenFileStreamAsync(filePath, FtpCommand.STOR), this));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates a directory on the FTP Server
        /// </summary>
        /// <param name="directory"></param>
        /// <returns></returns>
        public async Task CreateDirectoryAsync(string directory)
        {
            if (directory.IsNullOrWhiteSpace() || directory.Equals("."))
            {
                throw new ArgumentOutOfRangeException(nameof(directory), "Directory supplied was not valid");
            }

            LoggerHelper.Debug($"[FtpClient] Creating directory {directory}");

            EnsureLoggedIn();

            await CreateDirectoryStructureRecursively(directory.Split('/'), directory.StartsWith("/"));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Lists all directories in the current working directory
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task DeleteFileAsync(string fileName)
        {
            EnsureLoggedIn();
            LoggerHelper.Debug($"[FtpClient] Deleting file {fileName}");
            var response = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.DELE,
                Data       = fileName
            });

            if (!response.IsSuccess)
            {
                throw new FtpException(response.ResponseMessage);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Determines the file size of the given file
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task <long> GetFileSizeAsync(string fileName)
        {
            EnsureLoggedIn();
            LoggerHelper.Debug($"[FtpClient] Getting file size for {fileName}");
            var sizeResponse = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.SIZE,
                Data       = fileName
            });

            if (sizeResponse.FtpStatusCode != FtpStatusCode.FileStatus)
            {
                throw new FtpException(sizeResponse.ResponseMessage);
            }

            long fileSize = long.Parse(sizeResponse.ResponseMessage);

            return(fileSize);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Opens a filestream to the given filename
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        private async Task <Stream> OpenFileStreamAsync(string fileName, FtpCommand command)
        {
            EnsureLoggedIn();
            LoggerHelper.Debug($"[FtpClient] Opening filestream for {fileName}, {command}");
            dataStream = await ConnectDataStreamAsync();

            var retrResponse = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = command,
                Data       = fileName
            });

            if ((retrResponse.FtpStatusCode != FtpStatusCode.DataAlreadyOpen) &&
                (retrResponse.FtpStatusCode != FtpStatusCode.OpeningData) &&
                (retrResponse.FtpStatusCode != FtpStatusCode.ClosingData))
            {
                throw new FtpException(retrResponse.ResponseMessage);
            }

            return(dataStream);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Deletes the given directory from the FTP server
        /// </summary>
        /// <param name="directory"></param>
        /// <returns></returns>
        public async Task DeleteDirectoryAsync(string directory)
        {
            if (directory.IsNullOrWhiteSpace() || directory.Equals("."))
            {
                throw new ArgumentOutOfRangeException(nameof(directory), "Directory supplied was not valid");
            }

            if (directory == "/")
            {
                return;
            }

            LoggerHelper.Debug($"[FtpClient] Deleting directory {directory}");

            EnsureLoggedIn();

            var rmdResponse = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
            {
                FtpCommand = FtpCommand.RMD,
                Data       = directory
            });

            switch (rmdResponse.FtpStatusCode)
            {
            case FtpStatusCode.CommandOK:
            case FtpStatusCode.FileActionOK:
                return;

            case FtpStatusCode.ActionNotTakenFileUnavailable:
                await DeleteNonEmptyDirectory(directory);

                return;

            default:
                throw new FtpException(rmdResponse.ResponseMessage);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Creates a directory structure recursively given a path
        /// </summary>
        /// <param name="directories"></param>
        /// <param name="isRootedPath"></param>
        /// <returns></returns>
        private async Task CreateDirectoryStructureRecursively(IEnumerable <string> directories, bool isRootedPath)
        {
            LoggerHelper.Debug($"[FtpClient] Creating directory structure recursively {string.Join("/", directories)}");
            string originalPath = WorkingDirectory;

            if (isRootedPath && directories.Any())
            {
                await ChangeWorkingDirectoryAsync("/");
            }

            if (!directories.Any())
            {
                return;
            }

            if (directories.Count() == 1)
            {
                await ControlStream.SendCommandAsync(new FtpCommandEnvelope
                {
                    FtpCommand = FtpCommand.MKD,
                    Data       = directories.First()
                });

                await ChangeWorkingDirectoryAsync(originalPath);

                return;
            }

            foreach (string directory in directories)
            {
                if (directory.IsNullOrWhiteSpace())
                {
                    continue;
                }

                var response = await ControlStream.SendCommandAsync(new FtpCommandEnvelope
                {
                    FtpCommand = FtpCommand.CWD,
                    Data       = directory
                });

                if (response.FtpStatusCode != FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                    continue;
                }

                await ControlStream.SendCommandAsync(new FtpCommandEnvelope
                {
                    FtpCommand = FtpCommand.MKD,
                    Data       = directory
                });

                await ControlStream.SendCommandAsync(new FtpCommandEnvelope
                {
                    FtpCommand = FtpCommand.CWD,
                    Data       = directory
                });
            }

            await ChangeWorkingDirectoryAsync(originalPath);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Provides a stream which contains the data of the given filename on the FTP server
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task <Stream> OpenFileReadStreamAsync(string fileName)
        {
            LoggerHelper.Debug($"[FtpClient] Opening file read stream for {fileName}");

            return(new FtpDataStream(await OpenFileStreamAsync(fileName, FtpCommand.RETR), this));
        }