File Upload Progress Meter

337 views
Skip to first unread message

Adam

unread,
Jul 4, 2012, 12:38:05 AM7/4/12
to mojol...@googlegroups.com
Hello All,

I am currently prototyping a number of solutions for providing a file upload progress meter for our Mojolicious application. I have looked into the documentation and realize that it is possible to hook after_build_tx in order to provide this functionality.


This is a very powerful hook and should not be used lightly, it makes some rather advanced features such as upload progress bars possible

Does anyone have any sample code that shows the use of after_build_tx for this purpose? If not could somebody point me to roughly what I would need to do to determine how much of the file has been uploaded?

I have also investigated using a client side solution (Unfortunately the majority of our users are on outdated browsers), and using an Apache or Nginx specific module but do not want to create any extra dependencies.

Any help would be great.

Thanks,
Adam MacLeod

Adam

unread,
Jul 4, 2012, 8:48:07 PM7/4/12
to mojol...@googlegroups.com
Hey All,

Have answered my own question so thought I might post a follow-up to let anyone having the same problem know my solution.

Warning: I am certainly not a Perl or Mojo expert so there might be some giant flaws in my approach :)


#!/usr/bin/env perl

#
# Prototype to measure upload progress under mojolicious.
#

# Instructions to test
# dd if=/dev/zero of=/tmp/file count=1 bs=4MiB #Generate a 4mb upload file
# hypnotoad ./myapp.pl #Run hypnotoad
# curl --limit-rate 1M -F file=@/tmp/file http://localhost:8080/ #Simulate form upload

use Mojolicious::Lite;

app->hook(after_build_tx => sub {
    my ($tx, $app) = @_;
    $tx->req->on(progress => sub{
        my $message = shift;
        return unless my $len = $message->headers->content_length;
        my $size = $message->content->progress;
        say 'Progress: ', $size == $len ? 100 : int($size / ($len / 100)), '%', " size: $size";
    })
});

post '/' => sub {
  my $self = shift;
  $self->render('index')
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!
 
It's pretty straight forward really. It's constructed from the various parts of the documentation, namely:

Note: This does not work when Mojo is running on PSGI. This is due to the fact that the PSGI layer handles the upload and then passes the request onto Mojo. I have successfully tested with Morbo and Hypnotoad.

Does anyone think it would be beneficial to clean the example up a bit and put it into the documentation somewhere? (The cookbook maybe?)

Cheers,

Adam MacLeod

Reply all
Reply to author
Forward
0 new messages