private async Task <ComplexSocket> GetPassiveComplexSocketAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "PASV"); if (!success) { return(null); } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return(null); } var ipEndPoint = FtpClientHelper.ParseIPEndPoint(ftpReply); if (ipEndPoint == null) { return(null); } var transferComplexSocket = ComplexSocket.CreateForTransfer(this, ipEndPoint); return(transferComplexSocket); }
/// <remarks>This code does sending specifically for the <paramref name="controlComplexSocket" /> and does some logging</remarks> private async Task <bool> SendAndLogAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken, string command, params object[] args) { command = string.Format(command, args); if (!command.EndsWith(Environment.NewLine)) { command = string.Concat(command, Environment.NewLine); } { var socketRequestEventArg = new SocketRequestEventArg(command); this.OnSocketRequestAsync(socketRequestEventArg); } { var buffer = this.Encoding.GetBytes(command); using (var memoryStream = new MemoryStream(buffer)) { var success = await controlComplexSocket.Socket.SendAsync(this.ChunkSendBufferSize, controlComplexSocket.GetSocketAsyncEventArgs, memoryStream, cancellationToken); return(success); } } }
internal SocketAsyncEventArgsUserToken(ComplexSocket complexSocket, TimeSpan timeout) { Contract.Requires(complexSocket != null); this._complexSocket = complexSocket; this._timeout = timeout; }
private async Task <bool> ChangeWorkingDirectoryAsync(ComplexSocket controlComplexSocket, string directory, CancellationToken cancellationToken, bool createDirectoryIfNotExists = false) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "CWD {0}", directory); if (!success) { return(false); } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); switch (ftpReply.FtpResponseType) { case FtpResponseType.PermanentNegativeCompletion: // TODO some parsing of the actual FtpReply.ResponseCode should be done in here. i assume 5xx-state means "directory does not exist" all the time, which might be wrong if (!createDirectoryIfNotExists) { return(false); } success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "MKD {0}", directory); if (!success) { return(false); } ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return(false); } goto case FtpResponseType.PositiveCompletion; case FtpResponseType.PositiveCompletion: this._currentFtpDirectory = FtpDirectory.Create(this._currentFtpDirectory, directory); break; default: return(false); } return(true); }
public static ComplexSocket CreateForTransfer(FtpClient ftpClient, IPEndPoint ipEndPoint) { // TODO this method should be moved to a factory // TODO add check for ftpClient.Port 0 - 0xffff var complexSocket = new ComplexSocket(ipEndPoint, false, ftpClient.SocketReceiveBufferSize, ftpClient.SocketSendBufferSize, ftpClient.SocketClientAccessPolicyProtocol); return(complexSocket); }
public static ComplexSocket CreateForControl(FtpClient ftpClient) { // TODO this method should be moved to a factory // TODO add check for ftpClient.Port 0 - 0xffff var endPoint = new DnsEndPoint(ftpClient.Server, ftpClient.Port); var complexSocket = new ComplexSocket(endPoint, true, ftpClient.SocketReceiveBufferSize, ftpClient.SocketSendBufferSize, ftpClient.SocketClientAccessPolicyProtocol); return(complexSocket); }
/// <remarks>This code does receiving specifically for the <paramref name="controlComplexSocket" /> and does some logging</remarks> private async Task <FtpReply> ReceiveAndLogAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { this.WaitBeforeReceive(); var ftpReply = await controlComplexSocket.Socket.GetFtpReplyAsync(this.ChunkReceiveBufferSize, controlComplexSocket.GetSocketAsyncEventArgs, this.Encoding, cancellationToken); { var socketResponseEventArg = new SocketResponseEventArg(ftpReply.Data); this.OnSocketResponseAsync(socketResponseEventArg); } return(ftpReply); }
private async Task <bool> GotoParentDirectoryAsync(ComplexSocket controlComplexSocket, FtpFileSystemObject ftpFileSystemObject, CancellationToken cancellationToken, bool createDirectoryIfNotExists = false) { var ftpDirectory = ftpFileSystemObject.GetParentFtpDirectory(); var directoryChanges = FtpClientHelper.DirectoryChanges(this._currentFtpDirectory, ftpDirectory); foreach (var directoryChange in directoryChanges) { if (string.Equals(directoryChange, FtpFileSystemObject.ParentChangeCommand)) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "CDUP"); if (success) { var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (ftpReply.Success) { this._currentFtpDirectory = this._currentFtpDirectory.GetParentFtpDirectory(); } } } else { var success = await this.ChangeWorkingDirectoryAsync(controlComplexSocket, directoryChange, cancellationToken, createDirectoryIfNotExists); if (!success) { return(false); } } } return(true); }
private bool EnsureConnection() { var controlComplexSocket = this._controlComplexSocket ?? this.CreateControlComplexSocket(); if (controlComplexSocket.Connected) { return(true); } { var success = controlComplexSocket.Connect(this.ConnectTimeout); if (!success) { return(false); } } { var complexResult = controlComplexSocket.Receive(this.Encoding, this.ReceiveTimeout); var success = complexResult.Success; if (!success) { return(false); } } { var success = controlComplexSocket.Authenticate(this.Username, this.Password, this.Encoding, this.SendTimeout, this.ReceiveTimeout); if (!success) { return(false); } } this._controlComplexSocket = controlComplexSocket; return(true); }
private async Task <FtpFeatures> GetFtpFeaturesAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "FEAT"); if (!success) { return(FtpFeatures.Unknown); } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return(FtpFeatures.Unknown); } var messages = ftpReply.Messages; var ftpFeatures = FtpClientHelper.ParseFtpFeatures(messages); return(ftpFeatures); }
public static ComplexSocket CreateForControl(FtpClient ftpClient) { // TODO this method should be moved to a factory // TODO add check for ftpClient.Port 0 - 0xffff var endPoint = new DnsEndPoint(ftpClient.Server, ftpClient.Port); var complexSocket = new ComplexSocket(endPoint, true, ftpClient.SocketReceiveBufferSize, ftpClient.SocketSendBufferSize, ftpClient.SocketClientAccessPolicyProtocol); return complexSocket; }
public static ComplexSocket CreateForTransfer(FtpClient ftpClient, IPEndPoint ipEndPoint) { // TODO this method should be moved to a factory // TODO add check for ftpClient.Port 0 - 0xffff var complexSocket = new ComplexSocket(ipEndPoint, false, ftpClient.SocketReceiveBufferSize, ftpClient.SocketSendBufferSize, ftpClient.SocketClientAccessPolicyProtocol); return complexSocket; }
/// <remarks>This code does receiving specifically for the <paramref name="controlComplexSocket" /> and does some logging</remarks> private async Task<FtpReply> ReceiveAndLogAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { this.WaitBeforeReceive(); var ftpReply = await controlComplexSocket.Socket.GetFtpReplyAsync(this.ChunkReceiveBufferSize, controlComplexSocket.GetSocketAsyncEventArgs, this.Encoding, cancellationToken); { var socketResponseEventArg = new SocketResponseEventArg(ftpReply.Data); this.OnSocketResponseAsync(socketResponseEventArg); } return ftpReply; }
private async Task<ComplexSocket> GetPassiveComplexSocketAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "PASV"); if (!success) { return null; } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return null; } var ipEndPoint = FtpClientHelper.ParseIPEndPoint(ftpReply); if (ipEndPoint == null) { return null; } var transferComplexSocket = ComplexSocket.CreateForTransfer(this, ipEndPoint); return transferComplexSocket; }
private async Task<ComplexSocket> EnsureConnectionAndAuthenticationAsync(CancellationToken cancellationToken) { var controlComplexSocket = this._controlComplexSocket ?? ComplexSocket.CreateForControl(this); if (!controlComplexSocket.Connected) { this._authenticated = false; var success = await controlComplexSocket.ConnectAsync(cancellationToken); if (!success) { controlComplexSocket = null; } else { var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { controlComplexSocket = null; } } } if (controlComplexSocket != null) { if (this._authenticated) { return controlComplexSocket; } FtpReply ftpReply; var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "USER {0}", this.Username); if (success) { ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (ftpReply.FtpResponseType == FtpResponseType.PositiveIntermediate) { success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "PASS {0}", this.Password); if (success) { ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); } else { ftpReply = FtpReply.Failed; } } } else { ftpReply = FtpReply.Failed; } this._authenticated = ftpReply.Success; if (!this._authenticated) { controlComplexSocket = null; } } this._controlComplexSocket = controlComplexSocket; return controlComplexSocket; }
private async Task<bool> GotoParentDirectoryAsync(ComplexSocket controlComplexSocket, FtpFileSystemObject ftpFileSystemObject, CancellationToken cancellationToken, bool createDirectoryIfNotExists = false) { var ftpDirectory = ftpFileSystemObject.GetParentFtpDirectory(); var directoryChanges = FtpClientHelper.DirectoryChanges(this._currentFtpDirectory, ftpDirectory); foreach (var directoryChange in directoryChanges) { if (string.Equals(directoryChange, FtpFileSystemObject.ParentChangeCommand)) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "CDUP"); if (success) { var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (ftpReply.Success) { this._currentFtpDirectory = this._currentFtpDirectory.GetParentFtpDirectory(); } } } else { var success = await this.ChangeWorkingDirectoryAsync(controlComplexSocket, directoryChange, cancellationToken, createDirectoryIfNotExists); if (!success) { return false; } } } return true; }
private async Task<bool> ChangeWorkingDirectoryAsync(ComplexSocket controlComplexSocket, string directory, CancellationToken cancellationToken, bool createDirectoryIfNotExists = false) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "CWD {0}", directory); if (!success) { return false; } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); switch (ftpReply.FtpResponseType) { case FtpResponseType.PermanentNegativeCompletion: // TODO some parsing of the actual FtpReply.ResponseCode should be done in here. i assume 5xx-state means "directory does not exist" all the time, which might be wrong if (!createDirectoryIfNotExists) { return false; } success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "MKD {0}", directory); if (!success) { return false; } ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return false; } goto case FtpResponseType.PositiveCompletion; case FtpResponseType.PositiveCompletion: this._currentFtpDirectory = FtpDirectory.Create(this._currentFtpDirectory, directory); break; default: return false; } return true; }
private async Task <ComplexSocket> EnsureConnectionAndAuthenticationAsync(CancellationToken cancellationToken) { var controlComplexSocket = this._controlComplexSocket ?? ComplexSocket.CreateForControl(this); if (!controlComplexSocket.Connected) { this._authenticated = false; var success = await controlComplexSocket.ConnectAsync(cancellationToken); if (!success) { controlComplexSocket = null; } else { var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { controlComplexSocket = null; } } } if (controlComplexSocket != null) { if (this._authenticated) { return(controlComplexSocket); } FtpReply ftpReply; var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "USER {0}", this.Username); if (success) { ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (ftpReply.FtpResponseType == FtpResponseType.PositiveIntermediate) { success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "PASS {0}", this.Password); if (success) { ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); } else { ftpReply = FtpReply.Failed; } } } else { ftpReply = FtpReply.Failed; } this._authenticated = ftpReply.Success; if (!this._authenticated) { controlComplexSocket = null; } } this._controlComplexSocket = controlComplexSocket; return(controlComplexSocket); }
private async Task<FtpFeatures> GetFtpFeaturesAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken) { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "FEAT"); if (!success) { return FtpFeatures.Unknown; } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return FtpFeatures.Unknown; } var messages = ftpReply.Messages; var ftpFeatures = FtpClientHelper.ParseFtpFeatures(messages); return ftpFeatures; }
/// <remarks>This code does sending specifically for the <paramref name="controlComplexSocket" /> and does some logging</remarks> private async Task<bool> SendAndLogAsync(ComplexSocket controlComplexSocket, CancellationToken cancellationToken, string command, params object[] args) { command = string.Format(command, args); if (!command.EndsWith(Environment.NewLine)) { command = string.Concat(command, Environment.NewLine); } { var socketRequestEventArg = new SocketRequestEventArg(command); this.OnSocketRequestAsync(socketRequestEventArg); } { var buffer = this.Encoding.GetBytes(command); using (var memoryStream = new MemoryStream(buffer)) { var success = await controlComplexSocket.Socket.SendAsync(this.ChunkSendBufferSize, controlComplexSocket.GetSocketAsyncEventArgs, memoryStream, cancellationToken); return success; } } }