public void GetFile(string remotePath, Stream outStream, bool restart) { if (remotePath == null) { throw new ArgumentNullException("remotePath"); } if (remotePath.Length == 0) { throw new ArgumentException("must contain a value", "remotePath"); } if (outStream == null) { throw new ArgumentNullException("outStream"); } if (outStream.CanWrite == false) { throw new ArgumentException("must be writable. The CanWrite property must return the value 'true'.", "outStream"); } FtpRequest request = new FtpRequest(base.CharacterEncoding, FtpCmd.Retr, remotePath); if (restart) { long remoteSize = GetFileSize(remotePath); if (outStream.Length == remoteSize) { return; } base.TransferData(TransferDirection.ToClient, request, outStream, outStream.Length - 1); } else { base.TransferData(TransferDirection.ToClient, request, outStream); } }
internal string TransferText(FtpRequest request) { Stream output = new MemoryStream(); TransferData(TransferDirection.ToClient, request, output); output.Position = 0; StreamReader reader = new StreamReader(output, _encoding); return reader.ReadToEnd(); }
public void GetFile(string remotePath, string localPath, FileAction action) { if (remotePath == null) { throw new ArgumentNullException("remotePath"); } if (remotePath.Length == 0) { throw new ArgumentException("must contain a value", "remotePath"); } if (localPath == null) { throw new ArgumentNullException("localPath"); } if (localPath.Length == 0) { throw new ArgumentException("must contain a value", "localPath"); } if (action == FileAction.None) { throw new ArgumentOutOfRangeException("action", "must contain a value other than 'Unknown'"); } localPath = CorrectLocalPath(localPath); WriteToLog(String.Format("Action='GetFile';Status='TransferBegin';LocalPath='{0}';RemotePath='{1}';FileAction='{1}'", localPath, remotePath, action)); FtpRequest request = new FtpRequest(base.CharacterEncoding, FtpCmd.Retr, remotePath); try { switch (action) { case FileAction.CreateNew: using (Stream localFile = File.Open(localPath, FileMode.CreateNew)) { base.TransferData(TransferDirection.ToClient, request, localFile); } break; case FileAction.Create: using (Stream localFile = File.Open(localPath, FileMode.Create)) { base.TransferData(TransferDirection.ToClient, request, localFile); } break; case FileAction.CreateOrAppend: using (Stream localFile = File.Open(localPath, FileMode.OpenOrCreate)) { localFile.Position = localFile.Length; base.TransferData(TransferDirection.ToClient, request, localFile); } break; case FileAction.Resume: using (Stream localFile = File.Open(localPath, FileMode.Open)) { long remoteSize = GetFileSize(remotePath); if (localFile.Length == remoteSize) { return; } base.TransferData(TransferDirection.ToClient, request, localFile, localFile.Length - 1); } break; case FileAction.ResumeOrCreate: if (File.Exists(localPath) && (new FileInfo(localPath)).Length > 0) { GetFile(remotePath, localPath, FileAction.Resume); } else { GetFile(remotePath, localPath, FileAction.Create); } break; } } catch (Exception ex) { WriteToLog(String.Format("Action='GetFile';Status='TransferError';LocalPath='{0}';RemotePath='{1}';FileAction='{1}';ErrorMessage='{2}", localPath, remotePath, action, ex.Message)); throw new FtpException(String.Format("An unexpected exception occurred while retrieving file '{0}'.", remotePath), base.LastResponse, ex); } WriteToLog(String.Format("Action='GetFile';Status='TransferSuccess';LocalPath='{0}';RemotePath='{1}';FileAction='{1}'", localPath, remotePath, action)); }
internal void TransferData(TransferDirection direction, FtpRequest request, Stream data, long restartPosition) { if (_commandConn == null || _commandConn.Connected == false) { throw new FtpConnectionClosedException("Connection is closed."); } if (request == null) { throw new ArgumentNullException("request", "value is required"); } if (data == null) { throw new ArgumentNullException("data", "value is required"); } switch (direction) { case TransferDirection.ToClient: if (!data.CanWrite) throw new FtpDataTransferException("Data transfer error. Data conn does not allow write operation."); break; case TransferDirection.ToServer: if (!data.CanRead) throw new FtpDataTransferException("Data transfer error. Data conn does not allow read operation."); break; } if (restartPosition > 0 && !data.CanSeek) { throw new FtpDataTransferException("Data transfer restart error. Data conn does not allow seek operation."); } try { OpenDataConn(); if (restartPosition > 0) { SendRequest(new FtpRequest(_encoding, FtpCmd.Rest, restartPosition.ToString(CultureInfo.InvariantCulture))); data.Position = restartPosition; } SendRequest(request); System.Threading.Thread.Sleep(5); WaitForDataConn(); if (_dataConn == null) { throw new FtpDataConnectionException("Unable to establish a data connection to the destination. The destination may have refused the connection."); } Stream conn = _dataConn.GetStream(); if (_securityProtocol != FtpSecurityProtocol.None) { conn = CreateSslStream(conn); } if (_isCompressionEnabled) { conn = CreateZlibStream(direction, conn); } switch (direction) { case TransferDirection.ToClient: TransferBytes(conn, data, _maxDownloadSpeed * 1024); break; case TransferDirection.ToServer: TransferBytes(data, conn, _maxUploadSpeed * 1024); break; } } finally { CloseDataConn(); } WaitForHappyCodes(FtpResponseCode.ClosingDataConnection); if (_hashAlgorithm != HashingFunction.None && request.IsFileTransfer) { DoIntegrityCheck(request, data, restartPosition); } }
internal void TransferData(TransferDirection direction, FtpRequest request, Stream data) { TransferData(direction, request, data, 0); }
internal void SendRequest(FtpRequest request) { if (_commandConn == null || _commandConn.Connected == false) { throw new FtpConnectionClosedException("Connection is closed."); } DontWaitForHappyCodes(); if (ClientRequest != null) { ClientRequest(this, new FtpRequestEventArgs(request)); } byte[] buffer = request.GetBytes(); try { _commandStream.Write(buffer, 0, buffer.Length); } catch (IOException ex) { throw new FtpConnectionBrokenException("Connection is broken. Failed to send command.", ex); } if (request.HasHappyCodes) { WaitForHappyCodes(request.GetHappyCodes()); } else { if (request.Command != FtpCmd.Quit) { Thread.Sleep(2000); } DontWaitForHappyCodes(); } }
private void DoIntegrityCheck(FtpRequest request, Stream stream, long restartPosition) { string path = request.Arguments[0]; long startPos = restartPosition; long endPos = stream.Length; string streamHash = ComputeChecksum(_hashAlgorithm, stream, startPos); string serverHash = GetChecksum(_hashAlgorithm, path, startPos, endPos); if (String.Compare(streamHash, serverHash, StringComparison.InvariantCultureIgnoreCase) != 0) { throw new FtpFileIntegrityException(String.Format("File integrity check failed. The destination integrity value '{0}' for the file '{1}' did not match the data transfer integrity value '{2}'.", serverHash, path, streamHash)); } }
public FtpRequestEventArgs(FtpRequest request) { _request = request; }