How do I ensure only Mojo::Asset::File is used for uploads?

123 views
Skip to first unread message

Nicky

unread,
Feb 3, 2018, 2:10:56 PM2/3/18
to Mojolicious
Hello,

I am writing a plugin that is meant to process uploaded files. However, when I upload a small file it internalizes as a Mojo::Asset::Memory object.
I want to ensure only Mojo::Asset::File is used.

For testing I simply :
MOJO_MAX_MEMORY_SIZE=1 PERL5LIB=lib ./bin/driver.pl

However, I would prefer a mechanism that is scoped within my plugin.

I have tried various ways to set
max_memory_size and trigger an upgrade but I just don't get it right.  Here is the relevant code snippet.
As you can see, if the upload is a Mojo::Asset::Memory object the external command execution won't work.

$r = $routes->post(  '/constellation/lint' => sub {
      my $c = shift;

      # Check file size
      return $c->render(text => 'File is too big.', status => 200)
        if $c->req->is_limit_exceeded;

      # Process uploaded file
      return $c->redirect_to('form') unless my $miffile = $c->param('mif');

      my $size = $miffile->size;
      my $name = $miffile->filename;
      my $path = $miffile->asset->path;
      my @cmd  = @CMD;
      push @cmd, $path;
      my ($out, $err);
      run3 \@cmd, undef, \$out, \$err;

...
}


Any pointers would be appreciated.

Nicky

Stefan Adams

unread,
Feb 3, 2018, 2:15:09 PM2/3/18
to mojolicious
Do you just need to move it to a file with move_to? Test if the object is a memory object and if so move_to a file and then proceed like normal?

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious+unsubscribe@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at https://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Nicky

unread,
Feb 3, 2018, 3:51:25 PM2/3/18
to Mojolicious
I thought I tried that. Do I need to create the temp file first? That I did not do. I was hoping for something more automatic.

I will just create the temp file myself if that's the proper procedure.

Thanks Stefan. I appreciate the help.

Nicky
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.

sri

unread,
Feb 3, 2018, 3:58:20 PM2/3/18
to Mojolicious
I thought I tried that. Do I need to create the temp file first?

No, something like this should work perfectly fine.

use Mojo::File 'tempfile';
...
$miffile->move_to(my $temp = tempfile);
say $tempfile->slurp;
...

--
sebastian

Nicky

unread,
Feb 3, 2018, 4:20:23 PM2/3/18
to Mojolicious
The following worked for me. I am not reading the file contents. I am passing the uploaded path to another script later on.
   
      my $path = $miffile->asset->path; # This is correct for Mojo::Asset::File
      my $tfile = File::Temp->new;
      if (! $miffile->asset->is_file) { # It's really a Mojo::Asset::Memory
         $miffile->move_to($tfile->filename); # Convert to file.
          $c->app->log->info("New File : ".$tfile->filename);
          $path = $tfile->filename;  # This is the path I want now.

      }
      my $size = $miffile->size;
      my $name = $miffile->filename;

      # Execute the external command :
      run3 ['myLint', $path ], \$in, \$out, \$err;

I will try to clean it up as you suggest. Thanks for the help and most importantly for Mojolicious.

Nicky

sri

unread,
Feb 3, 2018, 4:29:53 PM2/3/18
to Mojolicious
We've been thinking about adding Mojo::Asset::*::to_file methods that would
guarantee a Mojo::Asset::File object, but it's so rarely needed that it doesn't
seem worth it.

--
sebastian

Nicky

unread,
Feb 3, 2018, 5:22:21 PM2/3/18
to Mojolicious
Understood.

I was originally not aware of the distinction within the Mojo;;Upload... until I read the documentation.  ;-)
I was always expecting a Mojo::File::Asset.  Since my real files are all large I did not notice until I started testing bad input and smaller files.

FYI: I could not get the tempfile method to work until I split out the assignment from the move_to. It returned a GLOB and not a path. That caused move_to to fail to convert.

This is what worked for me:
    (undef, $path) = tempfile; # I only care about the path.
    $miffile->move_to($path);


I am not sure why. I am using perl 5.22.4 and a fairly recent Mojolicious.

I also now have to handle the temporary file deletion on my own. Mojo::File::Asset gave me that for free. I may re-code it with a File::Temp object...

It works! I am happy. Thanks again.

Nicky
Reply all
Reply to author
Forward
0 new messages