private static IEnumerable <FtpCommand> Collect(FtpCommandCollector collector, string data) { var temp = collector.Encoding.GetBytes(data); foreach (var escapedDataMemory in EscapeTelnetCodes(temp)) { var collected = collector.Collect(escapedDataMemory.Span); foreach (var command in collected) { yield return(command); } } }
private static IEnumerable <FtpCommand> Collect(IFtpConnection connection, FtpCommandCollector collector, string data) { var temp = collector.Encoding.GetBytes(data); foreach (var escapedData in EscapeIAC(temp).Select(x => x.Span.ToArray())) { var collected = collector.Collect(connection, escapedData, 0, escapedData.Length); foreach (var command in collected) { yield return(command); } } }
private IEnumerable <FtpCommand> Collect(FtpCommandCollector collector, string data) { var temp = collector.Encoding.GetBytes(data); return(collector.Collect(temp, 0, temp.Length)); }
private async Task ProcessMessages() { Log?.Info($"Connected from {RemoteAddress.ToString(true)}"); using (var collector = new FtpCommandCollector(() => Encoding)) { await WriteAsync(new FtpResponse(220, "FTP Server Ready"), _cancellationTokenSource.Token); var buffer = new byte[1024]; try { Task<int> readTask = null; for (; ;) { if (readTask == null) readTask = SocketStream.ReadAsync(buffer, 0, buffer.Length, _cancellationTokenSource.Token); var tasks = new List<Task>() { readTask }; if (_activeBackgroundTask != null) tasks.Add(_activeBackgroundTask); Debug.WriteLine($"Waiting for {tasks.Count} tasks"); var completedTask = Task.WaitAny(tasks.ToArray(), _cancellationTokenSource.Token); Debug.WriteLine($"Task {completedTask} completed"); if (completedTask == 1) { var response = _activeBackgroundTask?.Result; if (response != null) Write(response); _activeBackgroundTask = null; } else { var bytesRead = readTask.Result; readTask = null; if (bytesRead == 0) break; var commands = collector.Collect(buffer, 0, bytesRead); foreach (var command in commands) { await ProcessMessage(command); } } } } catch (OperationCanceledException) { // Ignore the OperationCanceledException // This is normal during disconnects } catch (Exception ex) { Log?.Error(ex, "Failed to process connection"); } finally { Log?.Info($"Disconnection from {RemoteAddress.ToString(true)}"); _closed = true; Data.BackgroundCommandHandler.Cancel(); if (!ReferenceEquals(SocketStream, OriginalStream)) { SocketStream.Dispose(); SocketStream = OriginalStream; } _socket.Dispose(); OnClosed(); } } }