/// <summary> /// Changes the working directory to the given value for the current session /// </summary> /// <param name="directory"></param> /// <returns></returns> public async Task ChangeWorkingDirectoryAsync(string directory) { LoggerHelper.Trace($"[FtpClient] changing directory to {directory}"); if (directory.IsNullOrWhiteSpace() || directory.Equals(".")) { throw new ArgumentOutOfRangeException(nameof(directory), "Directory supplied was incorrect"); } EnsureLoggedIn(); var response = await ControlStream.SendCommandAsync(new FtpCommandEnvelope { FtpCommand = FtpCommand.CWD, Data = directory }); if (!response.IsSuccess) { throw new FtpException(response.ResponseMessage); } var pwdResponse = await ControlStream.SendCommandAsync(FtpCommand.PWD); if (!response.IsSuccess) { throw new FtpException(response.ResponseMessage); } WorkingDirectory = pwdResponse.ResponseMessage.Split('"')[1]; }
/// <summary> /// Determines the type of directory listing the FTP server will return, and set the appropriate parser /// </summary> /// <returns></returns> private IDirectoryProvider DetermineDirectoryProvider() { LoggerHelper.Trace("[FtpClient] Determining directory provider"); if (this.UsesMlsd()) { return(new MlsdDirectoryProvider(this, Configuration)); } return(new ListDirectoryProvider(this, Configuration)); }
/// <summary> /// Closes the write stream and associated socket (if open), /// </summary> /// <param name="ctsToken"></param> /// <returns></returns> public async Task CloseFileDataStreamAsync(CancellationToken ctsToken = default(CancellationToken)) { LoggerHelper.Trace("[FtpClient] Closing write file stream"); dataStream.Dispose(); if (ControlStream != null) { await ControlStream.GetResponseAsync(ctsToken); } }
private async Task <IEnumerable <string> > DetermineFeaturesAsync() { EnsureLoggedIn(); LoggerHelper.Trace("[FtpClient] Determining features"); var response = await ControlStream.SendCommandAsync(FtpCommand.FEAT); if (response.FtpStatusCode == FtpStatusCode.CommandSyntaxError || response.FtpStatusCode == FtpStatusCode.CommandNotImplemented) { return(Enumerable.Empty <string>()); } var features = response.Data.Where(x => !x.StartsWith(((int)FtpStatusCode.SystemHelpReply).ToString()) && !x.IsNullOrWhiteSpace()) .Select(x => x.Replace(Constants.CARRIAGE_RETURN, string.Empty).Trim()) .ToList(); return(features); }
/// <summary> /// Determines the file size of the given file /// </summary> /// <param name="transferMode"></param> /// <param name="secondType"></param> /// <returns></returns> public async Task SetTransferMode(FtpTransferMode transferMode, char secondType = '\0') { EnsureLoggedIn(); LoggerHelper.Trace($"[FtpClient] Setting transfer mode {transferMode}, {secondType}"); var response = await ControlStream.SendCommandAsync(new FtpCommandEnvelope { FtpCommand = FtpCommand.TYPE, Data = secondType != '\0' ? $"{(char)transferMode} {secondType}" : $"{(char)transferMode}" }); if (!response.IsSuccess) { throw new FtpException(response.ResponseMessage); } }
/// <summary> /// Attemps to log the user out asynchronously, sends the QUIT command and terminates the command socket. /// </summary> public async Task LogOutAsync() { await IgnoreStaleData(); if (!IsConnected) { return; } LoggerHelper.Trace("[FtpClient] Logging out"); await ControlStream.SendCommandAsync(FtpCommand.QUIT); ControlStream.Disconnect(); if (LocalEndPoint != null) { LocalEndPoint = null; } IsAuthenticated = false; }
/// <summary> /// Produces a data socket using Passive (PASV) or Extended Passive (EPSV) mode /// </summary> /// <returns></returns> internal async Task <Stream> ConnectDataStreamAsync() { if (UsePassive) { LoggerHelper.Trace("[FtpClient] Connecting to a data socket"); var epsvResult = await ControlStream.SendCommandAsync(FtpCommand.EPSV); int?passivePortNumber; if (epsvResult.FtpStatusCode == FtpStatusCode.EnteringExtendedPassive) { passivePortNumber = epsvResult.ResponseMessage.ExtractEpsvPortNumber(); } else { // EPSV failed - try regular PASV var pasvResult = await ControlStream.SendCommandAsync(FtpCommand.PASV); if (pasvResult.FtpStatusCode != FtpStatusCode.EnteringPassive) { throw new FtpException(pasvResult.ResponseMessage); } passivePortNumber = pasvResult.ResponseMessage.ExtractPasvPortNumber(); } if (!passivePortNumber.HasValue) { throw new FtpException("Could not determine EPSV/PASV data port"); } return(await ControlStream.OpenDataStreamAsync(Configuration.Host, passivePortNumber.Value, CancellationToken.None)); } else { return(await PortDataStreamAsync()); } }