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."); }