FubarDevelopment / FtpServer

Portable FTP server written in .NET
http://fubardevelopment.github.io/FtpServer/
MIT License
473 stars 161 forks source link

Callback when command like STOR has completed #94

Open justinstenning opened 4 years ago

justinstenning commented 4 years ago

While using the S3 provider, we need to know when an FTP operation is complete (e.g. the file has been uploaded and now exists on S3).

In reviewing issue #14 , it looked like this should be possible:

The above works even when the command is a background command. The code after the await will definitely be executed after the command was processed.

Yes the commands are all hit before the next line of code, however testing this with the S3 provider shows that the code after the await next(context) continues BEFORE the S3 provider uploads the file (e.g. before CreateAsync is called).

Is there something else I'm missing or an issue in the implemetation of the S3 provider, or is the only reliable way to do this with a custom provider?

I think it would be a common requirement to perform some action after the successfull completion of an upload/delete or whatever. Perhaps an additional middleware that occurs afterwards or an addition to the IFtpCommandMiddleware to support this behaviour?

justinstenning commented 4 years ago

For our situation, the FTP client always disconnects after the file upload is done.

Therefore we can use the context.Connection.Closed event handler like so:

context.Connection.Closed += (s, e) =>
    {
        ...
    }
};
black-snake commented 4 years ago

While using the S3 provider, we need to know when an FTP operation is complete (e.g. the file has been uploaded and now exists on S3).

In reviewing issue #14 , it looked like this should be possible:

The above works even when the command is a background command. The code after the await will definitely be executed after the command was processed.

Yes the commands are all hit before the next line of code, however testing this with the S3 provider shows that the code after the await next(context) continues BEFORE the S3 provider uploads the file (e.g. before CreateAsync is called).

Is there something else I'm missing or an issue in the implemetation of the S3 provider, or is the only reliable way to do this with a custom provider?

I think it would be a common requirement to perform some action after the successfull completion of an upload/delete or whatever. Perhaps an additional middleware that occurs afterwards or an addition to the IFtpCommandMiddleware to support this behaviour?

I experienced the same behavior with DotNet file system.

I have a custom class implementing IFtpCommandMiddleware and my if expression is also evaluated before the STOR command saves the file (fully) on the disk. (await next(context); does not help...)


public async Task InvokeAsync(FtpExecutionContext context, FtpCommandExecutionDelegate next)
{
    await next(context);

    if (context.Command.Name == "STOR" && !context.CommandAborted.IsCancellationRequested)
    {
        // handling code here
    }
}

I cannot rely on the client closing the connection immediately after transmission of one file. I particularly was very happy to see an FTP server implementation with which I can reliably determine when a file has been uploaded completely. Now this seems impossible from what I read and experience.

Any suggestions on how to proceed?


EDIT: When I immediately check after await next(context) if the file to upload exists, I get false.

victorperez2911 commented 3 years ago

I also have this problem, did anyone find any solution?

albertoVieiraNeto commented 3 years ago

@fubar-coder Can i consider that the only way to do this would be to overwrite the class DotNetFileSystemProvider and DotNetFileSystem creating my own callback on the CreateAsync method?

provider

FileSystem

fubar-coder commented 3 years ago

@albertoVieiraNeto Correct

BlakeAtLynx commented 1 year ago

@fubar-coder Can i consider that the only way to do this would be to overwrite the class DotNetFileSystemProvider and DotNetFileSystem creating my own callback on the CreateAsync method?

provider

FileSystem

Did you have success in that? Could you share?