handleCommand method

Future<void> handleCommand(
  1. String commandLine,
  2. FtpSession session
)

Implementation

Future<void> handleCommand(String commandLine, FtpSession session) async {
  List<String> parts = commandLine.split(' ');
  String command = parts[0].toUpperCase();
  String argument = parts.length > 1 ? parts.sublist(1).join(' ').trim() : '';

  logger.logCommand(command, argument);

  // Enforce authentication when credentials are configured
  if (!session.isAuthenticated &&
      !_preAuthCommands.contains(command) &&
      (session.username != null || session.password != null)) {
    session.sendResponse('530 Not logged in');
    return;
  }

  switch (command) {
    case 'USER':
      handleUser(argument, session);
      break;
    case 'PASS':
      handlePass(argument, session);
      break;
    case 'QUIT':
      await handleQuit(session);
      break;
    case 'AUTH':
      await handleAuth(argument, session);
      break;
    case 'PBSZ':
      handlePbsz(argument, session);
      break;
    case 'PROT':
      handleProt(argument, session);
      break;
    case 'CCC':
      session.sendResponse('534 CCC denied by server policy');
      break;
    case 'PASV':
      if (session.epsvAllMode) {
        session.sendResponse('503 PASV not allowed after EPSV ALL');
      } else {
        await session.enterPassiveMode();
      }
      break;
    case 'PORT':
      if (session.epsvAllMode) {
        session.sendResponse('503 PORT not allowed after EPSV ALL');
      } else {
        await session.enterActiveMode(argument);
      }
      break;
    case 'LIST':
      await session.listDirectory(_stripListFlags(argument));
      break;
    case 'NLST':
      await session.listDirectoryNames(_stripListFlags(argument));
      break;
    case 'RETR':
      await session.retrieveFile(argument);
      break;
    case 'STOR':
      if (session.serverType == ServerType.readOnly) {
        session.sendResponse('550 Command not allowed in read-only mode');
      } else {
        await session.storeFile(argument);
      }
      break;
    case 'CWD':
      session.changeDirectory(argument);
      break;
    case 'CDUP':
      session.changeToParentDirectory();
      break;
    case 'MKD':
    case 'XMKD':
      if (session.serverType == ServerType.readOnly) {
        session.sendResponse('550 Command not allowed in read-only mode');
      } else {
        await session.makeDirectory(argument);
      }
      break;
    case 'RMD':
    case 'XRMD':
      if (session.serverType == ServerType.readOnly) {
        session.sendResponse('550 Command not allowed in read-only mode');
      } else {
        await session.removeDirectory(argument);
      }
      break;
    case 'DELE':
      if (session.serverType == ServerType.readOnly) {
        session.sendResponse('550 Command not allowed in read-only mode');
      } else {
        await session.deleteFile(argument);
      }
      break;
    case 'SYST':
      session.sendResponse('215 UNIX Type: L8');
      break;
    case 'NOOP':
      session.sendResponse('200 NOOP command successful');
      break;
    case 'TYPE':
      handleType(argument, session);
      break;
    case 'SIZE':
      await session.fileSize(argument);
      break;
    case 'PWD':
    case 'XPWD':
      handleCurPath(session);
      break;
    case 'OPTS':
      handleOptions(argument, session);
      break;
    case 'FEAT':
      handleFeat(session);
      break;
    case 'EPSV':
      await handleEpsv(argument, session);
      break;
    case 'ABOR':
      session.abortTransfer();
      break;
    case 'MLSD':
      await session.handleMlsd(argument);
      break;
    case 'MDTM':
      session.handleMdtm(argument);
      break;
    case 'RNFR':
      handleRnfr(argument, session);
      break;
    case 'RNTO':
      await handleRnto(argument, session);
      break;
    case 'RENAME':
      await handleRename(argument, session);
      break;
    case 'STRU':
      handleStru(argument, session);
      break;
    case 'MODE':
      handleMode(argument, session);
      break;
    case 'ALLO':
      handleAllo(argument, session);
      break;
    case 'STAT':
      await handleStat(argument, session);
      break;
    case 'HELP':
      handleHelp(session);
      break;
    case 'SITE':
      handleSite(argument, session);
      break;
    case 'ACCT':
      handleAcct(argument, session);
      break;
    case 'REIN':
      handleRein(session);
      break;
    default:
      session.sendResponse('502 Command not implemented');
      break;
  }
}