Пример #1
0
        /// <summary>
        /// Verifies that provided password is correct for the user.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var user =
                knownUsers
                .FirstOrDefault(u =>
                                u.Name == session.Username &&
                                u.Password == arguments);

            if (user == null)
            {
                session.Logger.WriteWarning(
                    TraceResources.InvalidLoginAttemptFormat,
                    session.Username,
                    arguments);

                return(FtpResponsesAsync.NotLoggedIn);
            }

            session.FileSystem       = user.FileSystem;
            session.CurrentDirectory = new VirtualPath();

            session.Logger.WriteInfo(TraceResources.UserLoggedInFormat, session.Username);

            return(FtpResponsesAsync.LoggedIn);
        }
Пример #2
0
        /// <summary>
        /// Enumerates list of items in the directory and sends them to the client over the data channel.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
        protected override async Task HandleDataCommand(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            IEnumerable <FileSystemItem> items = null;

            if (String.IsNullOrEmpty(arguments) || ListAll.Equals(arguments, StringComparison.OrdinalIgnoreCase))
            {
                items = await session.FileSystem.ListItems(session.CurrentDirectory, cancellation);
            }
            else
            {
                var itemPath = session.CurrentDirectory.Clone();

                if (itemPath.Navigate(arguments))
                {
                    var item = await session.FileSystem.GetItem(itemPath, cancellation);

                    if (item != null)
                    {
                        items = new[] { item };
                    }
                }
            }

            if (items == null)
            {
                await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);

                return;
            }

            await WriteToDataChannel(session, WriteFileList, items, cancellation);
        }
        /// <summary>
        /// Enumerates list of item names in the directory and sends them to the client over the data channel.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
        protected override async Task HandleDataCommand(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var requestedPath = session.CurrentDirectory;

            if (!String.IsNullOrEmpty(arguments))
            {
                requestedPath = requestedPath.Clone();

                if (!requestedPath.Navigate(arguments))
                {
                    await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);

                    return;
                }
            }

            var items = await session.FileSystem.ListItems(requestedPath, cancellation);

            if (items == null)
            {
                await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);

                return;
            }

            await WriteToDataChannel(session, WriteFileList, items, cancellation);
        }
Пример #4
0
        /// <summary>
        /// Renames the file in the file system.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var sourcePath = session.RenameSource;

            session.RenameSource = null;

            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var targetPath = session.CurrentDirectory.Clone();

            if (targetPath.Navigate(arguments))
            {
                if (await session.FileSystem.IsFileExist(sourcePath, cancellation) &&
                    await session.FileSystem.RenameFile(sourcePath, targetPath, cancellation))
                {
                    session.Logger.WriteInfo(TraceResources.RenamedFileFormat, sourcePath, targetPath);
                    return(FtpResponses.FileActionOk);
                }

                if (await session.FileSystem.IsDirectoryExist(sourcePath, cancellation) &&
                    await session.FileSystem.RenameDirectory(sourcePath, targetPath, cancellation))
                {
                    session.Logger.WriteInfo(TraceResources.RenamedDirectoryFormat, sourcePath, targetPath);
                    return(FtpResponses.FileActionOk);
                }
            }

            return(FtpResponses.FileUnavailable);
        }
Пример #5
0
        /// <summary>
        /// Obtains the size of the file in the file system.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            if (session.TransferType != FileTransferType.Image)
            {
                // Only return size in Image file transfer mode
                return(FtpResponses.FileUnavailable);
            }

            var itemPath = session.CurrentDirectory.Clone();

            FileSystemItem item = null;

            if (itemPath.Navigate(arguments))
            {
                item = await session.FileSystem.GetItem(itemPath, cancellation);
            }

            if (item == null || item.IsDirectory)
            {
                return(FtpResponses.FileUnavailable);
            }

            return(FtpResponses.FileStatus(item.Size.ToString(CultureInfo.InvariantCulture)));
        }
        /// <summary>
        /// Obtains the restart offset from the FTP session context and transfers the file.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
        protected sealed override Task HandleDataCommand(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var restartOffset = session.TransferRestartOffset;

            session.TransferRestartOffset = 0;

            return(HandleFileTransferCommand(arguments, session, restartOffset, cancellation));
        }
Пример #7
0
        /// <summary>
        /// Verifies that provided user has access to the server.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (!knownUsers.Any(u => u.Name == arguments))
            {
                return(FtpResponsesAsync.InvalidUsername);
            }

            session.Username = arguments;
            return(FtpResponsesAsync.UserOk);
        }
        /// <summary>
        /// Verifies user authentication status and performs all necessary actions for the command.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
        public override async Task Handle(IArrayBufferView arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (session.FileSystem == null)
            {
                await session.ControlChannel.Send(FtpResponses.NotLoggedIn, cancellation);

                return;
            }

            await base.Handle(arguments, session, cancellation);
        }
        /// <summary>
        /// Closes the active data channel.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            try
            {
                session.DataChannel.Dispose();
            }
            catch { }

            session.DataChannel = null;

            return(FtpResponsesAsync.TransferComplete);
        }
        /// <summary>
        /// Changes the current path to the parent directory.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var newPath = session.CurrentDirectory.Clone();

            if (newPath.NavigateUp() && await session.FileSystem.IsDirectoryExist(newPath, cancellation))
            {
                session.CurrentDirectory = newPath;
                return(FtpResponses.FileActionOk);
            }

            return(FtpResponses.FileUnavailable);
        }
        /// <summary>
        /// Sends the requested file to the client over the data channel.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="restartOffset">File transfer restart offset</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
        protected override async Task HandleFileTransferCommand(
            string arguments,
            FtpSessionState session,
            long restartOffset,
            CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                await session.ControlChannel.Send(FtpResponses.ParameterSyntaxError, cancellation);

                return;
            }

            var filePath = session.CurrentDirectory.Clone();

            if (filePath.Navigate(arguments))
            {
                using (var fileStream = await session.FileSystem.ReadFile(filePath, cancellation))
                {
                    if (fileStream == null)
                    {
                        await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);

                        return;
                    }

                    if (restartOffset > 0)
                    {
                        try
                        {
                            await fileStream.SetOffset(restartOffset);
                        }
                        catch
                        {
                            // If offset is out of range
                            await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);

                            return;
                        }
                    }

                    if (await WriteToDataChannel(session, SendFile, fileStream, cancellation) ==
                        FtpResponses.TransferComplete)
                    {
                        session.Logger.WriteInfo(TraceResources.RetrievedFileFormat, filePath);
                    }
                }
            }
            else
            {
                await session.ControlChannel.Send(FtpResponses.FileUnavailable, cancellation);
            }
        }
        /// <summary>
        /// Sends the file contents to the client over the data channel.
        /// </summary>
        /// <param name="dataStream">Data channel stream</param>
        /// <param name="session">FTP session context</param>
        /// <param name="fileStream">Source file stream</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>Always returns <see cref="FtpResponses.TransferComplete"/>.</returns>
        private async Task <IResponse> SendFile(
            Stream dataStream,
            FtpSessionState session,
            Stream fileStream,
            CancellationToken cancellation)
        {
            await fileStream.CopyToAsync(dataStream);

            await dataStream.FlushAsync(cancellation);

            return(FtpResponses.TransferComplete);
        }
Пример #13
0
        /// <summary>
        /// Stores the offset to restart the next file transfer from in the FTP session context.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            long offset;

            if (!long.TryParse(arguments, out offset))
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            session.TransferRestartOffset = offset;

            return(FtpResponsesAsync.FileMoreInfoRequired);
        }
        /// <summary>
        /// Verifies if requested file structure is supported by the server.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            if (FileStructure.Equals(arguments, StringComparison.OrdinalIgnoreCase))
            {
                return(FtpResponsesAsync.Success);
            }

            return(FtpResponsesAsync.NotImplementedForParameter);
        }
Пример #15
0
        /// <summary>
        /// Creates a new passive mode data channel for the FTP session.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var channel =
                new PassiveDataChannel(
                    new IPEndPoint(session.ServerAddress, 0),
                    new LoggerScope(TraceResources.PassiveModeLoggerScope, session.Logger));

            session.DataChannel = channel;

            return
                (FtpResponsesAsync.PassiveMode(
                     session.PublicServerAddress.GetAddressBytes(),
                     channel.EndPoint.Port));
        }
Пример #16
0
        /// <summary>
        /// Changes the current path to the new one.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var newPath = session.CurrentDirectory.Clone();

            if (newPath.Navigate(arguments) && await session.FileSystem.IsDirectoryExist(newPath, cancellation))
            {
                session.CurrentDirectory = newPath;
                return(FtpResponses.FileActionOk);
            }

            return(FtpResponses.FileUnavailable);
        }
Пример #17
0
        /// <summary>
        /// Deletes a file from the file system.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var itemPath = session.CurrentDirectory.Clone();

            if (itemPath.Navigate(arguments) && await session.FileSystem.RemoveFile(itemPath, cancellation))
            {
                session.Logger.WriteInfo(TraceResources.DeletedFileFormat, itemPath);
                return(FtpResponses.FileActionOk);
            }

            return(FtpResponses.FileUnavailable);
        }
Пример #18
0
        /// <summary>
        /// Writes data to the currently active data channel.
        /// </summary>
        /// <typeparam name="TState">Type of the state object to pass to writer delegate.</typeparam>
        /// <param name="session">FTP session state</param>
        /// <param name="writer">Delegate that writes the actual data to the data channel</param>
        /// <param name="state">State object to pass to writer delegate</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response.</returns>
        protected async Task <IResponse> WriteToDataChannel <TState>(
            FtpSessionState session,
            Func <Stream, FtpSessionState, TState, CancellationToken, Task <IResponse> > writer,
            TState state,
            CancellationToken cancellation)
        {
            var dataChannel = session.DataChannel;

            if (dataChannel == null)
            {
                await session.ControlChannel.Send(FtpResponses.CanNotOpenDataChannel, cancellation);

                return(FtpResponses.CanNotOpenDataChannel);
            }

            IResponse transferResult;

            try
            {
                using (var dataStream = await dataChannel.GetDataStream())
                {
                    await session.ControlChannel.Send(FtpResponses.OpenningDataChannel, cancellation);

                    transferResult = await writer(dataStream, session, state, cancellation);
                }
            }
            catch (ObjectDisposedException)
            {
                await session.ControlChannel.Send(FtpResponses.CanNotOpenDataChannel, cancellation);

                return(FtpResponses.CanNotOpenDataChannel);
            }

            try
            {
                session.DataChannel.Dispose();
            }
            catch { }

            session.DataChannel = null;

            await session.ControlChannel.Send(transferResult, cancellation);

            return(transferResult);
        }
Пример #19
0
        /// <summary>
        /// Logs out current user without disconnecting the client socket.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            try
            {
                session.DataChannel.Dispose();
            }
            catch { }

            session.DataChannel      = null;
            session.Username         = null;
            session.FileSystem       = null;
            session.CurrentDirectory = null;

            session.PathEncoding = Encoding.ASCII;
            session.TransferType = FileTransferType.ASCII;

            return(FtpResponsesAsync.ServiceReady);
        }
Пример #20
0
        /// <summary>
        /// Creates a new directory in the file system.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var itemPath = session.CurrentDirectory.Clone();

            if (itemPath.Navigate(arguments) && await session.FileSystem.CreateDirectory(itemPath, cancellation))
            {
                var itemPathString = itemPath.ToString();
                session.Logger.WriteInfo(TraceResources.CreatedDirectoryFormat, itemPathString);
                return(FtpResponses.Path(itemPathString, session.PathEncoding));
            }

            return(FtpResponses.FileUnavailable);
        }
Пример #21
0
        /// <summary>
        /// Receives the file from the client over the data channel.
        /// </summary>
        /// <param name="dataStream">Data channel stream</param>
        /// <param name="session">FTP session context</param>
        /// <param name="fileStream">Target file stream</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP response that should be sent to the client.</returns>
        private async Task <IResponse> ReceiveFile(
            Stream dataStream,
            FtpSessionState session,
            Stream fileStream,
            CancellationToken cancellation)
        {
            try
            {
                await dataStream.CopyToAsync(fileStream);

                await fileStream.FlushAsync(cancellation);

                return(FtpResponses.TransferComplete);
            }
            catch (NotEnoughSpaceException)
            {
                return(FtpResponses.NotEnoughSpace);
            }
        }
Пример #22
0
        /// <summary>
        /// Stores the original file name in the FTP session context.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var sourcePath = session.CurrentDirectory.Clone();

            if (sourcePath.Navigate(arguments) &&
                (await session.FileSystem.IsFileExist(sourcePath, cancellation) ||
                 await session.FileSystem.IsDirectoryExist(sourcePath, cancellation)))
            {
                session.RenameSource = sourcePath;
                return(FtpResponses.FileMoreInfoRequired);
            }

            return(FtpResponses.FileUnavailable);
        }
Пример #23
0
        /// <summary>
        /// Updates the current FTP session context with the requested options.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var optionArguments = arguments.Split(' ');

            if (optionArguments.Length == 0)
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            if (FtpOptions.UTF8.Equals(optionArguments[0], StringComparison.OrdinalIgnoreCase))
            {
                if (optionArguments.Length == 1)
                {
                    return(FtpResponsesAsync.ParameterSyntaxError);
                }

                if (FtpOptions.SetOn.Equals(optionArguments[1], StringComparison.OrdinalIgnoreCase))
                {
                    session.PathEncoding = Encoding.UTF8;
                }
                else if (FtpOptions.SetOff.Equals(optionArguments[1], StringComparison.OrdinalIgnoreCase))
                {
                    session.PathEncoding = Encoding.ASCII;
                }
                else
                {
                    return(FtpResponsesAsync.ParameterSyntaxError);
                }

                return(FtpResponsesAsync.Success);
            }
            else if (FtpOptions.UTF_8.Equals(optionArguments[0], StringComparison.OrdinalIgnoreCase))
            {
                session.PathEncoding = Encoding.UTF8;
                // TODO: Support NLST argument
                return(FtpResponsesAsync.Success);
            }
            else
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }
        }
        /// <summary>
        /// Sends the list of file system item names to the client over the data channel.
        /// </summary>
        /// <param name="dataStream">Data channel stream</param>
        /// <param name="session">FTP session context</param>
        /// <param name="items">File system items</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>Always returns <see cref="FtpResponses.TransferComplete"/>.</returns>
        private async Task <IResponse> WriteFileList(
            Stream dataStream,
            FtpSessionState session,
            IEnumerable <FileSystemItem> items,
            CancellationToken cancellation)
        {
            byte[] recordBuffer;

            foreach (var item in items)
            {
                recordBuffer = session.PathEncoding.GetBytes(item.Name);
                await dataStream.WriteAsync(recordBuffer, 0, recordBuffer.Length, cancellation);

                await dataStream.WriteAsync(session.LineFeed, 0, session.LineFeed.Length, cancellation);
            }

            await dataStream.WriteAsync(session.LineFeed, 0, session.LineFeed.Length, cancellation);

            await dataStream.FlushAsync(cancellation);

            return(FtpResponses.TransferComplete);
        }
Пример #25
0
        /// <summary>
        /// Creates a new active mode data channel for the FTP session.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            var segments = arguments.Split(',');

            EndPoint endPoint;

            if (!TryGetEndPoint(segments, out endPoint))
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            session.DataChannel =
                new ActiveDataChannel(
                    endPoint,
                    new LoggerScope(TraceResources.ActiveModeLoggerScope, session.Logger));

            return(FtpResponsesAsync.Success);
        }
Пример #26
0
        /// <summary>
        /// Updates the transfer type in the FTP session context.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            var typeArguments = arguments.Split(' ');

            if (typeArguments.Length == 0)
            {
                return(FtpResponsesAsync.ParameterSyntaxError);
            }

            switch (typeArguments[0])
            {
            case AsciiTransferType:
                session.TransferType = FileTransferType.ASCII;

                if (typeArguments.Length > 1)
                {
                    switch (typeArguments[1])
                    {
                    case NonPrintFormat:
                        return(FtpResponsesAsync.Success);

                    default:
                        return(FtpResponsesAsync.NotImplementedForParameter);
                    }
                }

                return(FtpResponsesAsync.Success);

            case ImageTransferType:
                session.TransferType = FileTransferType.Image;
                return(FtpResponsesAsync.Success);

            default:
                return(FtpResponsesAsync.NotImplementedForParameter);
            }
        }
        /// <summary>
        /// Obtains the last modification time of the file system item.
        /// </summary>
        /// <param name="arguments">Command arguments</param>
        /// <param name="session">FTP session context</param>
        /// <param name="cancellation">Cancellation token</param>
        /// <returns>FTP server response to send to the client.</returns>
        protected override async Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
        {
            if (String.IsNullOrEmpty(arguments))
            {
                return(FtpResponses.ParameterSyntaxError);
            }

            var itemPath = session.CurrentDirectory.Clone();

            FileSystemItem item = null;

            if (itemPath.Navigate(arguments))
            {
                item = await session.FileSystem.GetItem(itemPath, cancellation);
            }

            if (item == null)
            {
                return(FtpResponses.FileUnavailable);
            }

            return(FtpResponses.FileStatus(
                       item.LastModifiedTime.ToString(TimestampFormat, CultureInfo.InvariantCulture)));
        }
Пример #28
0
 /// <summary>
 /// Converts command arguments from binary form to string using current paths encoding.
 /// </summary>
 /// <param name="arguments">Arguments in binary form</param>
 /// <param name="session">FTP session context</param>
 /// <returns>Command arguments as string.</returns>
 protected override string ReadArguments(IArrayBufferView arguments, FtpSessionState session)
 {
     return(arguments.ToString(session.PathEncoding));
 }
Пример #29
0
 /// <summary>
 /// Performs all necessary actions for the data command.
 /// </summary>
 /// <param name="arguments">Command arguments</param>
 /// <param name="session">FTP session context</param>
 /// <param name="cancellation">Cancellation token</param>
 /// <returns>A <see cref="Task"/> that represents an asynchronous operation.</returns>
 protected abstract Task HandleDataCommand(string arguments, FtpSessionState session, CancellationToken cancellation);
Пример #30
0
 /// <summary>
 /// This method is not used by data commands, as data commands return multiple responses during the data transfer.
 /// </summary>
 /// <param name="arguments">Command arguments</param>
 /// <param name="session">FTP session state</param>
 /// <param name="cancellation">Cancellation token</param>
 /// <returns>FTP server response.</returns>
 protected sealed override Task <IResponse> Handle(string arguments, FtpSessionState session, CancellationToken cancellation)
 {
     throw new NotImplementedException();
 }