Dancer2 icon indicating copy to clipboard operation
Dancer2 copied to clipboard

Uploaded file not deleted - "Directory not empty"

Open realflash opened this issue 1 year ago • 2 comments

Current CPAN version of Dancer2 1.1.0 Running under Strawberry Perl (64-bit) Portable 5.38.2.2-64bit on Windows 11

Here's the handler:

post '/ingest' => sub {
   my $file = request->upload('uploaded_file');
   $log->debug("Uploaded file saved to ".$file->tempname);
   return template 'uploaded';;
};

Here's the result:

C:\Users\****\dev\pcnm_windows>.\run_dev.bat
Watching lib ****\bin\app.psgi for file updates.
2024/07/02 10:59:41 TRACE Built config from files: C:\Users\*****\config.yml C:\Users\****\environments\development.yml
HTTP::Server::PSGI: Accepting connections at http://0:5000/
2024/07/02 10:59:47 TRACE looking for post /ingest
2024/07/02 10:59:47 TRACE Entering hook core.app.before_request
2024/07/02 10:59:47 DEBUG Uploaded file saved to C:\Users\****\AppData\Local\Temp\Beq0v\qjP4TSSqP0
2024/07/02 10:59:47 TRACE Entering hook core.app.after_request
127.0.0.1 - - [02/Jul/2024:10:59:47 +0100] "POST /ingest HTTP/1.1" 200 8116 "http://localhost:5000/ingest" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
cannot remove directory for C:/Users/****/AppData/Local/Temp/Beq0v: Directory not empty at C:/Users/****/dev/pcnm_windows/dist/perl/perl/lib/File/Temp.pm line 2643.

The file is not deleted, and I assume it is meant to be though that is not clear from the POD for this class.

realflash avatar Jul 02 '24 10:07 realflash

Hacky workaround:

use File::Path qw/ rmtree /;
use File::Basename;

post '/ingest' => sub {
   my $file = request->upload('uploaded_file');
   $log->debug("Uploaded file saved to ".$file->tempname);

    # Do all the things you need to do with the file first

    # Make sure file is actually deleted
    my ($name, $path, $suffix) = fileparse($file->tempname);
    if($^O =~ /^MSWin/)
    {
        my $result = `rmdir /s /q "$path" 2>&1`;
        die "Error deleting file $path: $result" if length($result) > 0;
    }
    else
    {
        rmtree($path);
    }
   return template 'uploaded';

Dancer (or whatever underlying library is used) seems not to object to the fact that the file is not there when DESTROY is called so there is no follow in error from doing this.

realflash avatar Jul 02 '24 11:07 realflash

@realflash thanks for the report! This will require some investigation.

cromedome avatar Jul 13 '24 16:07 cromedome

I think https://github.com/PerlDancer/Dancer2/blob/main/t/request_upload.t#L137 provides the answer: apparently Windows can't remove file/link while open due to deadlock.

In any case, we're getting the upload files from Plack, so there is not much we could do. :-(

@cromedome I think we should close this. Agree?

yanick avatar Jun 12 '25 23:06 yanick

@yanick Agree, thanks for the investigation!

cromedome avatar Jun 12 '25 23:06 cromedome