Ejemplo n.º 1
0
        private async Task ProcessCommandAsync(string message)
        {
            var messageSegs = message.Split(new[] { ' ' }, 2);
            var command     = messageSegs[0];
            var parameter   = messageSegs.Length < 2 ? string.Empty : messageSegs[1];

            server.Tracer.TraceCommand(command, remoteEndPoint);
            switch (command.ToUpper())
            {
            case "RNFR":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await CommandRnfrAsync(parameter);

                return;

            case "RNTO":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await ReplyAsync(FtpReplyCode.BadSequence, "Should use RNFR first");

                return;

            case "DELE":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await fileProvider.DeleteAsync(parameter);
                await ReplyAsync(FtpReplyCode.FileActionOk, "Delete succeeded");

                return;

            case "RMD":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await fileProvider.DeleteDirectoryAsync(parameter);
                await ReplyAsync(FtpReplyCode.FileActionOk, "Directory deleted");

                return;

            case "MKD":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await fileProvider.CreateDirectoryAsync(parameter);
                await ReplyAsync(
                    FtpReplyCode.PathCreated,
                    string.Format(
                        "\"{0}\"",
                        fileProvider.GetWorkingDirectory().Replace("\"", "\"\"")));

                return;

            case "PWD":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                await ReplyAsync(
                    FtpReplyCode.PathCreated,
                    string.Format(
                        "\"{0}\"",
                        fileProvider.GetWorkingDirectory().Replace("\"", "\"\"")));

                return;

            case "SYST":
                await ReplyAsync(FtpReplyCode.NameSystemType, "UNIX simulated by .NET Core");

                return;

            case "FEAT":
                await ReplyMultilineAsync(FtpReplyCode.SystemStatus, "Supports:\nUTF8");

                return;

            case "OPTS":
                if (parameter.ToLowerInvariant() == "UTF8 ON")
                {
                    encoding = Encoding.UTF8;
                    await ReplyAsync(FtpReplyCode.CommandOkay, "UTF-8 is on");

                    return;
                }
                else if (parameter.ToUpper() == "UTF8 OFF")
                {
                    encoding = Encoding.ASCII;
                    await ReplyAsync(FtpReplyCode.CommandOkay, "UTF-8 is off");

                    return;
                }
                break;

            case "USER":
                userName      = parameter;
                authenticated = false;
                fileProvider  = null;
                await ReplyAsync(FtpReplyCode.NeedPassword, "Please input password");

                return;

            case "PASS":
                if (authenticated = server.Authenticator.Authenticate(userName, parameter))
                {
                    await ReplyAsync(FtpReplyCode.UserLoggedIn, "Logged in");

                    fileProvider = server.FileManager.GetProvider(userName);
                }
                else
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "Failed to log in");

                    fileProvider = null;
                }
                return;

            case "PORT":
                await CommandPortAsync(parameter);

                return;

            case "EPRT":
                await CommandEprtAsync(parameter);

                return;

            case "PASV":
                await CommandPasvAsync();

                return;

            case "EPSV":
                await CommandEpsvAsync(parameter);

                return;

            case "TYPE":
                switch (parameter)
                {
                case "A":
                    dataType = DataType.ASCII;
                    await ReplyAsync(FtpReplyCode.CommandOkay, "In ASCII type");

                    return;

                case "I":
                    dataType = DataType.IMAGE;
                    await ReplyAsync(FtpReplyCode.CommandOkay, "In IMAGE type");

                    return;

                default:
                    await ReplyAsync(FtpReplyCode.ParameterNotImplemented, "Unknown type");

                    return;
                }

            case "MODE":
                if (parameter == "S")
                {
                    transmissionMode = TransmissionMode.Stream;
                    await ReplyAsync(FtpReplyCode.CommandOkay, "In stream mode");
                }
                else
                {
                    await ReplyAsync(FtpReplyCode.ParameterNotImplemented, "Unknown mode");
                }

                return;

            case "QUIT":
                if (server.ControlConnectionSslFactory != null)
                {
                    await server.ControlConnectionSslFactory.DisconnectAsync(stream);
                }
                throw new QuitRequestedException();

            case "RETR":
                await CommandRetrAsync(parameter);

                return;

            case "STOR":
                await CommandStorAsync(parameter);

                return;

            case "CWD":
                if (!authenticated)
                {
                    await ReplyAsync(FtpReplyCode.NotLoggedIn, "You need to log in first");

                    return;
                }
                if (fileProvider.SetWorkingDirectory(parameter))
                {
                    await ReplyAsync(FtpReplyCode.FileActionOk, fileProvider.GetWorkingDirectory());
                }
                else
                {
                    await ReplyAsync(FtpReplyCode.FileNoAccess, "Path doesn't exist");
                }
                return;

            case "NLST":
                await CommandNlstAsync(parameter);

                return;

            case "LIST":
                await CommandListAsync(parameter);

                return;

            case "NOOP":
                await ReplyAsync(FtpReplyCode.CommandOkay, "OK");

                return;

            case "AUTH":
                await CommandAuthAsync(parameter);

                return;

            case "PROT":
                await CommandProtAsync(parameter);

                return;
            }
            await ReplyAsync(FtpReplyCode.CommandUnrecognized, "Can't recognize this command.");
        }