From 10a8dd8603a6d532a9cda1cd05702cf706067c01 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 4 Oct 2015 01:39:52 +0200 Subject: [PATCH] Add max size handling --- lib/Lufi/Controller/Files.pm | 116 +++++++++++++------------ lufi.conf.template | 5 ++ public/js/lufi-up.js | 160 ++++++++++++++++++++--------------- templates/index.html.ep | 2 +- 4 files changed, 160 insertions(+), 123 deletions(-) diff --git a/lib/Lufi/Controller/Files.pm b/lib/Lufi/Controller/Files.pm index 360ce0c..52f8d09 100644 --- a/lib/Lufi/Controller/Files.pm +++ b/lib/Lufi/Controller/Files.pm @@ -7,6 +7,7 @@ use LufiDB; use Lufi::File; use Lufi::Slice; use File::Spec::Functions; +use Number::Bytes::Human qw(format_bytes); sub upload { my $c = shift; @@ -23,65 +24,76 @@ sub upload { $c->debug('Got message'); - my $f; - if (defined($json->{id})) { - my @records = LufiDB::Files->select('WHERE short = ?', $json->{id}); - $f = Lufi::File->new(record => $records[0]); - } else { - my $delay; + my $over_size = 0; + # Check against max_size + if (defined $c->config('max_file_size')) { + if ($json->{size} > $c->config('max_file_size')) { + $over_size = 1; + $c->send(sprintf('{"success": false, "msg":"'.$c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))).'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i})); + } + } - if (defined $c->config('delay_for_size')) { - # Choose delay according to config - my $delays = $c->config('delay_for_size'); - my @keys = sort {$b <=> $a} keys %{$delays}; - for my $key (@keys) { - if ($json->{size} >= $key) { - $delay = ($json->{delay} < $delays->{$key}) ? $json->{delay} : $delays->{$key}; - last; + unless ($over_size) { + my $f; + if (defined($json->{id})) { + my @records = LufiDB::Files->select('WHERE short = ?', $json->{id}); + $f = Lufi::File->new(record => $records[0]); + } else { + my $delay; + + if (defined $c->config('delay_for_size')) { + # Choose delay according to config + my $delays = $c->config('delay_for_size'); + my @keys = sort {$b <=> $a} keys %{$delays}; + for my $key (@keys) { + if ($json->{size} >= $key) { + $delay = ($json->{delay} < $delays->{$key}) ? $json->{delay} : $delays->{$key}; + last; + } } } - } - # If the file size is lower than the lowest configured size or if there is no delay_for_size setting, we choose the configured max delay - unless (defined $delay) { - $delay = ($json->{delay} <= $c->config('max_delay') || $c->config('max_delay') == 0) ? $json->{delay} : $c->config('max_delay'); - } + # If the file size is lower than the lowest configured size or if there is no delay_for_size setting, we choose the configured max delay + unless (defined $delay) { + $delay = ($json->{delay} <= $c->config('max_delay') || $c->config('max_delay') == 0) ? $json->{delay} : $c->config('max_delay'); + } - $f = Lufi::File->new( - record => $c->get_empty, - created_by => $c->ip, - delete_at_first_view => ($json->{del_at_first_view}) ? 1 : 0, - delete_at_day => $delay, - mediatype => $json->{type}, - filename => $json->{name}, - filesize => $json->{size}, - nbslices => $json->{total}, - mod_token => $c->shortener($c->config('token_length')) + $f = Lufi::File->new( + record => $c->get_empty, + created_by => $c->ip, + delete_at_first_view => ($json->{del_at_first_view}) ? 1 : 0, + delete_at_day => $delay, + mediatype => $json->{type}, + filename => $json->{name}, + filesize => $json->{size}, + nbslices => $json->{total}, + mod_token => $c->shortener($c->config('token_length')) + ); + $f->write; + } + # Create directory + my $dir = catdir('files', $f->short); + mkdir($dir, 0700) unless (-d $dir); + + # Create slice file + my $file = catfile($dir, $json->{part}.'.part'); + my $s = Lufi::Slice->new( + short => $f->short, + j => $json->{part}, + path => $file ); + spurt $text, $file; + push @{$f->slices}, $s; + + if (($json->{part} + 1) == $json->{total}) { + $f->complete(1); + $f->created_at(time); + $c->provisioning; + } + $f->write; + + $ws->send(sprintf('{"success": true, "i": %d, "j": %d, "parts": %d, "short": "%s", "name": "%s", "size": %d, "del_at_first_view": %s, "created_at": %d, "delay": %d, "token": "%s", "sent_delay": %d}', $json->{i}, $json->{part}, $json->{total}, $f->short, $f->filename, $f->filesize, (($f->delete_at_first_view) ? 'true' : 'false'), $f->created_at, $f->delete_at_day, $f->mod_token, $json->{delay})); } - # Create directory - my $dir = catdir('files', $f->short); - mkdir($dir, 0700) unless (-d $dir); - - # Create slice file - my $file = catfile($dir, $json->{part}.'.part'); - my $s = Lufi::Slice->new( - short => $f->short, - j => $json->{part}, - path => $file - ); - spurt $text, $file; - push @{$f->slices}, $s; - - if (($json->{part} + 1) == $json->{total}) { - $f->complete(1); - $f->created_at(time); - $c->provisioning; - } - - $f->write; - - $ws->send(sprintf('{"success": true, "i": %d, "j": %d, "parts": %d, "short": "%s", "name": "%s", "size": %d, "del_at_first_view": %s, "created_at": %d, "delay": %d, "token": "%s"}', $json->{i}, $json->{part}, $json->{total}, $f->short, $f->filename, $f->filesize, (($f->delete_at_first_view) ? 'true' : 'false'), $f->created_at, $f->delete_at_day, $f->mod_token)); } ); $c->on( diff --git a/lufi.conf.template b/lufi.conf.template index d1613a9..5bf3fcc 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -33,6 +33,11 @@ # optional, default is 32 #token_length => 32, + # max file size, in octets + # you can write it 100*1024*1024 + # optional, no default + #max_file_size => 104857600, + # if you want to have piwik statistics, provide a piwik image tracker # only the image tracker is allowed, no javascript # optional, no default diff --git a/public/js/lufi-up.js b/public/js/lufi-up.js index 63cedc9..0a6b325 100644 --- a/public/js/lufi-up.js +++ b/public/js/lufi-up.js @@ -191,89 +191,114 @@ function sliceAndUpload(randomkey, i, parts, j, delay, del_at_first_view, short) // Update the progress bar function updateProgressBar(data) { var i = data.i; - var j = data.j; - var parts = data.parts; - var short = data.short; + var sent_delay = data.sent_delay; var del_at_first_view = data.del_at_first_view; - var created_at = data.created_at; - var delay = data.delay; + if (data.success) { + var j = data.j; + var delay = data.delay; + var parts = data.parts; + var short = data.short; + var created_at = data.created_at; - var dp = document.getElementById('progress-'+window.fc); - var key = dp.getAttribute('data-key'); + var dp = document.getElementById('progress-'+window.fc); + var key = dp.getAttribute('data-key'); - if (j + 1 === parts) { - var n = document.getElementById('name-'+window.fc); - var d = document.createElement('div'); - var url = baseURL+'r/'+short+'#'+key; - var del_url = baseURL+'d/'+short+'/'+data.token; - var links = encodeURIComponent('["'+short+'"]'); - var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); - n.innerHTML = n.innerHTML+'
'+limit; - d.innerHTML = '
' - +'
'; + if (j + 1 === parts) { + var n = document.getElementById('name-'+window.fc); + var d = document.createElement('div'); + var url = baseURL+'r/'+short+'#'+key; + var del_url = baseURL+'d/'+short+'/'+data.token; + var links = encodeURIComponent('["'+short+'"]'); + var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); + n.innerHTML = n.innerHTML+'
'+limit; + d.innerHTML = '
' + +'
'; - var p2 = dp.parentNode; - var p1 = p2.parentNode; + var p2 = dp.parentNode; + var p1 = p2.parentNode; - p2.remove(); - p1.appendChild(d); + p2.remove(); + p1.appendChild(d); - // Add copy all and mailto buttons - var misc = document.getElementById('misc'); - if (misc.innerHTML === '') { - misc.innerHTML = ''+i18n.copyAll+' '+i18n.mailTo+''; + // Add copy all and mailto buttons + var misc = document.getElementById('misc'); + if (misc.innerHTML === '') { + misc.innerHTML = ''+i18n.copyAll+' '+i18n.mailTo+''; + } else { + updateMailLink(); + } + + // Add the file to localStorage + addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token); + + // Upload next file + window.fc++; + i++; + if (i < window.files.length) { + uploadFile(i, sent_delay, del_at_first_view); + } else { + // We have finished + window.removeEventListener('onbeforeunload', confirmExit); + document.getElementById('delete-day').removeAttribute('disabled'); + document.getElementById('first-view').removeAttribute('disabled'); + } } else { - updateMailLink(); + j++; + // Update progress bar + var percent = Math.round(100 * j/parts); + dp.style.width = percent+'%'; + dp.setAttribute('aria-valuenow', percent); + + // Encrypt and upload next slice + sliceAndUpload(key, i, parts, j, delay, del_at_first_view, short); } + } else { + var n = document.getElementById('name-'+window.fc); + var p = document.getElementById('progress-'+window.fc); + var d = document.createElement('div'); - // Add the file to localStorage - addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token); + p.parentNode.remove(); + d.innerHTML = data.msg; + d.setAttribute('class', 'alert alert-danger'); + n.parentNode.appendChild(d); + // Upload next file window.fc++; i++; if (i < window.files.length) { - uploadFile(i, delay, del_at_first_view); + uploadFile(i, sent_delay, del_at_first_view); } else { // We have finished window.removeEventListener('onbeforeunload', confirmExit); document.getElementById('delete-day').removeAttribute('disabled'); document.getElementById('first-view').removeAttribute('disabled'); } - } else { - j++; - // Update progress bar - var percent = Math.round(100 * j/parts); - dp.style.width = percent+'%'; - dp.setAttribute('aria-valuenow', percent); - - // Encrypt and upload next slice - sliceAndUpload(key, i, parts, j, delay, del_at_first_view, short); } } @@ -304,12 +329,7 @@ function spawnWebsocket(callback) { console.log('Connection is closed.'); } ws.onmessage = function(e) { - var data = JSON.parse(e.data); - if (data.success) { - updateProgressBar(data); - } else { - alert(data.msg); - } + updateProgressBar(JSON.parse(e.data)); } ws.onerror = function() { console.log('error'); diff --git a/templates/index.html.ep b/templates/index.html.ep index 2d11644..1189487 100644 --- a/templates/index.html.ep +++ b/templates/index.html.ep @@ -76,7 +76,7 @@ var i18n = { hit: '<%= l('Hit Enter, then Ctrl+C to copy the download link') %>', hits: '<%= l('Hit Enter, then Ctrl+C to copy all the download links') %>', mailTo: '<%= l('Send all links by email') %>', - noLimit: '<%= l('No limit') %>', + noLimit: '<%= l('No expiration delay') %>', }; % end %= javascript '/js/sjcl.js'