public void TestIncomplete()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = Collect(collector, "TEST");

            Assert.Equal(new FtpCommand[0], commands);
            Assert.False(collector.IsEmpty);
        }
        public void TestCompleteCarriageReturnWithLineFeed()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = Collect(collector, "TEST\r\n");

            Assert.Equal(
                new[] { new FtpCommand("TEST", string.Empty) },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        public void TestWithArgument()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TEST 1\r"));
            Assert.Equal(
                new[] { new FtpCommand("TEST", "1") },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        public void TestMultipleWithSecondIncomplete()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TEST1\rTEST2"));
            Assert.Equal(
                new[] { new FtpCommand("TEST1", string.Empty) },
                commands,
                new FtpCommandComparer());
            Assert.False(collector.IsEmpty);
        }
        public void TestMultipleWithoutLineFeed()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TEST1\r"));
            commands.AddRange(Collect(collector, "TEST2\r\n"));
            Assert.Equal(
                new[] { new FtpCommand("TEST1", string.Empty), new FtpCommand("TEST2", string.Empty) },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        public void TestCompleteInTwoSteps()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TES"));
            commands.AddRange(Collect(collector, "T\r\n"));
            Assert.Equal(
                new[] { new FtpCommand("TEST", string.Empty), },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        public void TestCompleteCarriageReturnWithLineFeedAtStepTwo()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TEST\r"));
            commands.AddRange(Collect(collector, "\n"));
            Assert.Equal(
                new[] { new FtpCommand("TEST", string.Empty), },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        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);
                }
            }
        }
        public void TestMultipleWithArgumentWithLineFeedInStepTwo()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            commands.AddRange(Collect(collector, "TEST 1\r"));
            commands.AddRange(Collect(collector, "\nTEST 2\r\n"));
            Assert.Equal(
                new[] { new FtpCommand("TEST", "1"), new FtpCommand("TEST", "2") },
                commands,
                new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
        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);
                }
            }
        }
        public void TestSingleChars()
        {
            var collector = new FtpCommandCollector(() => Encoding.UTF8);
            var commands  = new List <FtpCommand>();

            foreach (var ch in "USER anonymous\r\n")
            {
                commands.AddRange(Collect(collector, $"{ch}"));
            }

            Assert.Equal(
                new[] { new FtpCommand("USER", "anonymous") },
                commands,
                new FtpCommandComparer());
        }
        public void TestWithCyrillicTextWithWindows1251Encoding()
        {
            var encoding  = CodePagesEncodingProvider.Instance.GetEncoding(codepage: 1251);
            var collector = new FtpCommandCollector(() => encoding);

            const string cyrillicSymbols = "абвгдеёжзийклмнопрстуфхцчшщыъьэюя";

            var expectedCommands = new[] { new FtpCommand("TEST", cyrillicSymbols) };

            var stringToTest   = string.Format("TEST {0}\r\n", cyrillicSymbols);
            var actualCommands = Collect(collector, stringToTest).ToArray();

            // Test failed
            // TELNET: Unknown command received - skipping 0xFF
            // 0xFF == 'я' (maybe?)
            Assert.Equal(expectedCommands, actualCommands, new FtpCommandComparer());
            Assert.True(collector.IsEmpty);
        }
Ejemplo n.º 13
0
        private IEnumerable <FtpCommand> Collect(FtpCommandCollector collector, string data)
        {
            var temp = collector.Encoding.GetBytes(data);

            return(collector.Collect(temp, 0, temp.Length));
        }
Ejemplo n.º 14
0
        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();
                }
            }
        }