From 1394469c06e6908e6e77b48718ce6664db23407c Mon Sep 17 00:00:00 2001 From: Jerome Jutteau Date: Sun, 10 Feb 2013 01:37:43 +0100 Subject: [PATCH] =?utf8?q?Bypass=20size=20limit=20by=20splitting=20big=20f?= =?utf8?q?iles=20on=20client=E2=80=99s=20side=20using=20HTML5=20file=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- admin.php | 20 ++++ file.php | 16 ++- index.php | 10 +- install.php | 2 +- lib/functions.js | 182 ++++++++++++++++++++++++++-- lib/functions.php | 294 ++++++++++++++++++++++++++++++++++++++++++++-- lib/lang/fr.php | 10 ++ lib/settings.php | 5 +- script.php | 121 ++++++++++++++++++- 9 files changed, 631 insertions(+), 29 deletions(-) mode change 100644 => 100755 index.php mode change 100644 => 100755 lib/functions.php diff --git a/admin.php b/admin.php index 87dbcea..bf61e6d 100755 --- a/admin.php +++ b/admin.php @@ -129,6 +129,18 @@ require (JIRAFEAU_ROOT . 'lib/template/header.php');
+ + + + + + + + + + +
+
@@ -201,6 +213,14 @@ if (isset ($_POST['action'])) echo t('Number of cleaned files') . ' : ' . $total; echo '

'; } + elseif (strcmp ($_POST['action'], 'clean_async') == 0) + { + $total = jirafeau_admin_clean_async (); + echo '
' . NL; + echo '

'; + echo t('Number of cleaned files') . ' : ' . $total; + echo '

'; + } elseif (strcmp ($_POST['action'], 'list') == 0) { jirafeau_admin_list ("", "", ""); diff --git a/file.php b/file.php index bb97570..17ef381 100644 --- a/file.php +++ b/file.php @@ -174,14 +174,24 @@ if ($cfg['download_page'] && !$password_challenged && !$button_download && !$but exit; } +header ('HTTP/1.0 200 OK'); header ('Content-Length: ' . $link['file_size']); -header ('Content-Type: ' . $link['mime_type']); if (!jirafeau_is_viewable ($link['mime_type']) || !$cfg['preview'] || $button_download) -{ header ('Content-Disposition: attachment; filename="' . $link['file_name'] . '"'); +else + header ('Content-Type: ' . $link['mime_type']); + +/* Read file */ +$r = fopen (VAR_FILES . $p . $link['md5'], 'r'); +while (!feof ($r)) +{ + print fread ($r, 1024); + ob_flush(); } -readfile (VAR_FILES . $p . $link['md5']); +fclose ($r); + +//readfile (VAR_FILES . $p . $link['md5']); if ($link['onetime'] == 'O') jirafeau_delete_link ($link_name); diff --git a/index.php b/index.php old mode 100644 new mode 100755 index da4cc40..d3c0df7 --- a/index.php +++ b/index.php @@ -69,15 +69,13 @@ if (has_error ()) document.getElementById('send').style.display = ''; "/>

-

- -

+

@@ -109,5 +107,9 @@ if (has_error ()) document.getElementById('upload_finished').style.display = 'none'; document.getElementById('options').style.display = 'none'; document.getElementById('send').style.display = 'none'; + if (!check_html5_file_api ()) + document.getElementById('max_file_size').innerHTML = ''; diff --git a/install.php b/install.php index a3db15b..c753c5b 100755 --- a/install.php +++ b/install.php @@ -95,7 +95,7 @@ jirafeau_check_var_dir ($path) $path . '
' . $solution_str . '
' . $mkdir_str2); - foreach (array ('files', 'links') as $subdir) + foreach (array ('files', 'links', 'async') as $subdir) { $subpath = $path.$subdir; diff --git a/lib/functions.js b/lib/functions.js index 15ae08c..aba302c 100755 --- a/lib/functions.js +++ b/lib/functions.js @@ -32,13 +32,17 @@ function show_link (url, reference, delete_code, date) } else document.getElementById('validity').style.display = 'none'; - document.getElementById('uploading').style.display = 'none'; document.getElementById('upload').style.display = 'none'; document.getElementById('upload_finished').style.display = ''; } +function show_upload_progression (p) +{ + document.getElementById('uploaded_percentage').innerHTML = p; +} + function upload_progress (e) { if (!e.lengthComputable) @@ -47,7 +51,7 @@ function upload_progress (e) * to give a response before providing the link. */ var p = Math.round (e.loaded * 99 / e.total); - document.getElementById('uploaded_percentage').innerHTML = p.toString() + '%'; + show_upload_progression (p.toString() + '%'); } function upload_failed (e) @@ -56,12 +60,12 @@ function upload_failed (e) alert ('Sorry, upload failed'); } -function upload (url, file, time, password, one_time) +function classic_upload (url, file, time, password, one_time) { var req = new XMLHttpRequest (); - req.upload.addEventListener("progress", upload_progress, false); - req.addEventListener("error", upload_failed, false); - req.addEventListener("abort", upload_failed, false); + req.upload.addEventListener ("progress", upload_progress, false); + req.addEventListener ("error", upload_failed, false); + req.addEventListener ("abort", upload_failed, false); req.onreadystatechange = function () { if (req.readyState == 4 && req.status == 200) @@ -83,6 +87,8 @@ function upload (url, file, time, password, one_time) d.setSeconds (d.getSeconds() + 604800); else if (time == 'month') d.setSeconds (d.getSeconds() + 2419200); + else + return; show_link (url, res[0], res[1], d.toString()); } else @@ -102,12 +108,170 @@ function upload (url, file, time, password, one_time) req.send (form); } -function start_upload (url) +function check_html5_file_api () +{ + if (window.File && window.FileReader && window.FileList && window.Blob) + return true; + return false; +} + +var async_global_transfered = 0; +var async_global_url = ''; +var async_global_file; +var async_global_ref = ''; +var async_global_max_size = 0; +var async_global_time; +var async_global_transfering = 0; + +function async_upload_start (url, max_size, file, time, password, one_time) { - upload (url, + async_global_transfered = 0; + async_global_url = url; + async_global_file = file; + async_global_max_size = max_size; + async_global_time = time; + + var req = new XMLHttpRequest (); + req.addEventListener ("error", upload_failed, false); + req.addEventListener ("abort", upload_failed, false); + req.onreadystatechange = function () + { + if (req.readyState == 4 && req.status == 200) + { + var res = req.responseText; + if (res == "Error") + return; + res = res.split ("\n"); + async_global_ref = res[0]; + var code = res[1]; + async_upload_push (code); + } + } + req.open ("POST", async_global_url + 'script.php?init_async' , true); + + var form = new FormData(); + form.append ("filename", async_global_file.name); + form.append ("type", async_global_file.type); + if (time) + form.append ("time", time); + if (password) + form.append ("key", password); + if (one_time) + form.append ("one_time_download", '1'); + req.send (form); +} + +function async_upload_progress (e) +{ + if (!e.lengthComputable && async_global_file.size != 0) + return; + var p = Math.round ((e.loaded + async_global_transfered) * 99 / (async_global_file.size)); + show_upload_progression (p.toString() + '%'); +} + +function async_upload_push (code) +{ + if (async_global_transfered == async_global_file.size) + { + async_upload_end (code); + return; + } + var req = new XMLHttpRequest (); + req.upload.addEventListener ("progress", async_upload_progress, false); + req.addEventListener ("error", upload_failed, false); + req.addEventListener ("abort", upload_failed, false); + req.onreadystatechange = function () + { + if (req.readyState == 4 && req.status == 200) + { + var res = req.responseText; + if (res == "Error") + return; + res = res.split ("\n"); + var code = res[0] + async_global_transfered = async_global_transfering; + async_upload_push (code); + } + } + req.open ("POST", async_global_url + 'script.php?push_async' , true); + + var chunk_size = parseInt (async_global_max_size * 0.90); + var start = async_global_transfered; + var end = start + chunk_size; + if (end >= async_global_file.size) + end = async_global_file.size; + var blob = async_global_file.slice (start, end); + async_global_transfering = end; + + var form = new FormData(); + form.append ("ref", async_global_ref); + form.append ("data", blob); + form.append ("code", code); + req.send (form); +} + +function async_upload_end (code) +{ + var req = new XMLHttpRequest (); + req.addEventListener ("error", upload_failed, false); + req.addEventListener ("abort", upload_failed, false); + req.onreadystatechange = function () + { + if (req.readyState == 4 && req.status == 200) + { + var res = req.responseText; + if (res == "Error") + return; + res = res.split ("\n"); + if (async_global_time != 'none') + { + var d = new Date(); + if (async_global_time == 'minute') + d.setSeconds (d.getSeconds() + 60); + else if (async_global_time == 'hour') + d.setSeconds (d.getSeconds() + 3600); + else if (async_global_time == 'day') + d.setSeconds (d.getSeconds() + 86400); + else if (async_global_time == 'week') + d.setSeconds (d.getSeconds() + 604800); + else if (async_global_time == 'month') + d.setSeconds (d.getSeconds() + 2419200); + else + return; + show_link (async_global_url, res[0], res[1], d.toString()); + } + else + show_link (async_global_url, res[0], res[1]); + } + } + req.open ("POST", async_global_url + 'script.php?end_async' , true); + + var form = new FormData(); + form.append ("ref", async_global_ref); + form.append ("code", code); + req.send (form); +} + +function upload (url, max_size) +{ + if (check_html5_file_api () + && document.getElementById('file_select').files[0].size >= max_size) + { + async_upload_start (url, + max_size, document.getElementById('file_select').files[0], document.getElementById('select_time').value, document.getElementById('input_key').value, document.getElementById('one_time_download').checked ); -} \ No newline at end of file + } + else + { + classic_upload (url, + document.getElementById('file_select').files[0], + document.getElementById('select_time').value, + document.getElementById('input_key').value, + document.getElementById('one_time_download').checked + ); + } +} diff --git a/lib/functions.php b/lib/functions.php old mode 100644 new mode 100755 index 898b6fc..9a9df71 --- a/lib/functions.php +++ b/lib/functions.php @@ -72,6 +72,24 @@ base_16_to_64 ($num) return $o; } +/** + * Generate a random code. + * @param $l code length + * @return random code. + */ +function +jirafeau_gen_random ($l) +{ + if ($l <= 0) + return 42; + + $code=""; + for ($i = 0; $i < $l; $i++) + $code .= dechex (rand (0, 15)); + + return $code; +} + function jirafeau_human_size ($octets) { @@ -147,6 +165,17 @@ function jirafeau_ini_to_bytes ($value) return $bytes; } +/** + * gets the maximum upload size according to php.ini + * @returns the maximum upload size in bytes + */ +function +jirafeau_get_max_upload_size_bytes () +{ + return min (jirafeau_ini_to_bytes (ini_get ('post_max_size')), + jirafeau_ini_to_bytes (ini_get ('upload_max_filesize'))); +} + /** * gets the maximum upload size according to php.ini * @returns the maximum upload size string @@ -326,7 +355,7 @@ jirafeau_upload ($file, $one_time_download, $key, $time, $ip) 'delete_link' => '')); } - /* increment or create count file */ + /* Increment or create count file. */ $counter = 0; if (file_exists (VAR_FILES . $p . $md5 . '_count')) { @@ -339,9 +368,7 @@ jirafeau_upload ($file, $one_time_download, $key, $time, $ip) fclose ($handle); /* Create delete code. */ - $delete_link_code = 0; - for ($i = 0; $i < 8; $i++) - $delete_link_code .= dechex (rand (0, 16)); + $delete_link_code = jirafeau_gen_random (8); /* md5 password or empty */ $password = ''; @@ -353,8 +380,8 @@ jirafeau_upload ($file, $one_time_download, $key, $time, $ip) $handle = fopen ($link_tmp_name, 'w'); fwrite ($handle, $name . NL. $mime_type . NL. $size . NL. $password . NL. $time . - NL . $md5. NL . ($one_time_download ? 'O' : 'R') . NL.date ('U') . - NL. $ip . NL. $delete_link_code . NL); + NL . $md5. NL . ($one_time_download ? 'O' : 'R') . NL . date ('U') . + NL . $ip . NL. $delete_link_code . NL); fclose ($handle); $md5_link = base_16_to_64 (md5_file ($link_tmp_name)); $l = s2p ("$md5_link"); @@ -405,7 +432,6 @@ jirafeau_is_viewable ($mime) return false; } - // Error handling functions. //! Global array that contains all registered errors. $error_list = array (); @@ -469,6 +495,9 @@ function check_errors () if (!is_writable (VAR_LINKS)) add_error (t('The link directory is not writable!'), VAR_LINKS); + + if (!is_writable (VAR_ASYNC)) + add_error (t('The async directory is not writable!'), VAR_ASYNC); /* Check if the install.php script is still in the directory. */ if (file_exists (JIRAFEAU_ROOT . 'install.php')) @@ -641,4 +670,253 @@ jirafeau_admin_clean () } return $count; } -?> + + +/** + * Clean old async transferts. + * @return number of cleaned files. + */ +function +jirafeau_admin_clean_async () +{ + $count = 0; + /* Get all links files. */ + $stack = array (VAR_ASYNC); + while (($d = array_shift ($stack)) && $d != NULL) + { + $dir = scandir ($d); + + foreach ($dir as $node) + { + if (strcmp ($node, '.') == 0 || strcmp ($node, '..') == 0 || + preg_match ('/\.tmp/i', "$node")) + continue; + + if (is_dir ($d . $node)) + { + /* Push new found directory. */ + $stack[] = $d . $node . '/'; + } + elseif (is_file ($d . $node)) + { + /* Read async informations. */ + $a = jirafeau_get_async_ref (basename ($node)); + if (!count ($a)) + continue; + /* Delete transferts older than 1 hour. */ + if (date ('U') - $a['last_edited'] > 3600) + { + jirafeau_async_delete (basename ($node)); + $count++; + } + } + } + } + return $count; +} +/** + * Read async transfert informations + * @return array containing informations. + */ +function +jirafeau_get_async_ref ($ref) +{ + $out = array (); + $refinfos = VAR_ASYNC . s2p ("$ref") . "$ref"; + + if (!file_exists ($refinfos)) + return $out; + + $c = file ($refinfos); + $out['file_name'] = trim ($c[0]); + $out['mime_type'] = trim ($c[1]); + $out['key'] = trim ($c[2], NL); + $out['time'] = trim ($c[3]); + $out['onetime'] = trim ($c[4]); + $out['ip'] = trim ($c[5]); + $out['last_edited'] = trim ($c[6]); + $out['next_code'] = trim ($c[7]); + return $out; +} + +/** + * Delete async transfert informations + */ +function +jirafeau_async_delete ($ref) +{ + $p = s2p ("$ref"); + if (file_exists (VAR_ASYNC . $p . $ref)) + unlink (VAR_ASYNC . $p . $ref); + if (file_exists (VAR_ASYNC . $p . $ref . '_data')) + unlink (VAR_ASYNC . $p . $ref . '_data'); + $parse = VAR_ASYNC . $p; + $scan = array(); + while (file_exists ($parse) + && ($scan = scandir ($parse)) + && count ($scan) == 2 // '.' and '..' folders => empty. + && basename ($parse) != basename (VAR_ASYNC)) + { + rmdir ($parse); + $parse = substr ($parse, 0, strlen($parse) - strlen(basename ($parse)) - 1); + } +} + +/** + * Init a new asynchronous upload. + * @param $finename Name of the file to send + * @param $one_time One time upload parameter + * @param $key eventual password (or blank) + * @param $time time limit + * @param $ip ip address of the client + * @return a string containing a temporary reference followed by a code or the string "Error" + */ +function +jirafeau_async_init ($filename, $type, $one_time, $key, $time, $ip) +{ + $res = 'Error'; + + /* Create temporary folder. */ + $ref; + $p; + $code = jirafeau_gen_random (4); + do + { + $ref = jirafeau_gen_random (32); + $p = VAR_ASYNC . s2p ($ref); + } while (file_exists ($p)); + @mkdir ($p, 0755, true); + if (!file_exists ($p)) + { + echo "Error"; + return; + } + + /* md5 password or empty */ + $password = ''; + if (!empty ($key)) + $password = md5 ($key); + + /* Store informations. */ + $p .= $ref; + $handle = fopen ($p, 'w'); + fwrite ($handle, + $filename . NL. $type . NL. $password . NL. $time . NL . + ($one_time ? 'O' : 'R') . NL . $ip . NL . date ('U') . NL . + $code . NL); + fclose ($handle); + + return $ref . NL . $code ; +} + +/** + * Append a piece of file on the asynchronous upload. + * @param $ref asynchronous upload reference + * @param $file piece of data + * @param $code client code for this operation + * @return a string containing a next code to use or the string "Error" + */ +function +jirafeau_async_push ($ref, $data, $code) +{ + /* Get async infos. */ + $a = jirafeau_get_async_ref ($ref); + + /* Check some errors. */ + if (count ($a) == 0 + || $a['next_code'] != "$code" + || empty ($data['tmp_name']) + || !is_uploaded_file ($data['tmp_name'])) + return "Error"; + + $p = s2p ($ref); + + /* Concatenate data. */ + $r = fopen ($data['tmp_name'], 'r'); + $w = fopen (VAR_ASYNC . $p . $ref . '_data', 'a'); + while (!feof ($r)) + { + if (fwrite ($w, fread ($r, 1024)) === false) + { + fclose ($r); + fclose ($w); + jirafeau_async_delete ($ref); + return "Error"; + } + } + fclose ($r); + fclose ($w); + unlink ($data['tmp_name']); + + /* Update async file. */ + $code = jirafeau_gen_random (4); + $handle = fopen (VAR_ASYNC . $p . $ref, 'w'); + fwrite ($handle, + $a['file_name'] . NL. $a['mime_type'] . NL. $a['key'] . NL . + $a['time'] . NL . $a['onetime'] . NL . $a['ip'] . NL . + date ('U') . NL . $code . NL); + fclose ($handle); + return $code; +} + +/** + * Finalyze an asynchronous upload. + * @param $ref asynchronous upload reference + * @param $code client code for this operation + * @return a string containing the download reference followed by a delete code or the string "Error" + */ +function +jirafeau_async_end ($ref, $code) +{ + /* Get async infos. */ + $a = jirafeau_get_async_ref ($ref); + if (count ($a) == 0 + || $a['next_code'] != "$code") + return "Error"; + + /* Generate link infos. */ + $p = VAR_ASYNC . s2p ($ref) . $ref . "_data"; + if (!file_exists($p)) + return "Error"; + $md5 = md5_file ($p); + $size = filesize($p); + $np = s2p ($md5); + $delete_link_code = jirafeau_gen_random (8); + + /* File already exist ? */ + if (!file_exists (VAR_FILES . $np)) + @mkdir (VAR_FILES . $np, 0755, true); + if (!file_exists (VAR_FILES . $np . $md5)) + rename ($p, VAR_FILES . $np . $md5); + + /* Increment or create count file. */ + $counter = 0; + if (file_exists (VAR_FILES . $np . $md5 . '_count')) + { + $content = file (VAR_FILES . $np . $md5. '_count'); + $counter = trim ($content[0]); + } + $counter++; + $handle = fopen (VAR_FILES . $np . $md5. '_count', 'w'); + fwrite ($handle, $counter); + fclose ($handle); + + /* Create link. */ + $link_tmp_name = VAR_LINKS . $md5 . rand (0, 10000) . ' .tmp'; + $handle = fopen ($link_tmp_name, 'w'); + fwrite ($handle, + $a['file_name'] . NL . $a['mime_type'] . NL . $size . NL . + $a['key'] . NL . $a['time'] . NL . $md5 . NL . $a['onetime'] . NL . + date ('U') . NL . $a['ip'] . NL . $delete_link_code . NL); + fclose ($handle); + $md5_link = base_16_to_64 (md5_file ($link_tmp_name)); + $l = s2p ("$md5_link"); + if (!@mkdir (VAR_LINKS . $l, 0755, true) || + !rename ($link_tmp_name, VAR_LINKS . $l . $md5_link)) + echo "Error"; + + /* Clean async upload. */ + jirafeau_async_delete ($ref); + return $md5_link . NL . $delete_link_code; +} +?> \ No newline at end of file diff --git a/lib/lang/fr.php b/lib/lang/fr.php index b25bd6c..00d31f1 100755 --- a/lib/lang/fr.php +++ b/lib/lang/fr.php @@ -37,6 +37,7 @@ $tr = array ( 'One month' => 'Un mois', 'The file directory is not writable' => 'Le dossier \'file\' ne peut être écrit.', 'The link directory is not writable' => 'Le dossier \'link\' ne peut être écrit.', + 'The async directory is not writable!' => 'Le dossier \'async\' ne peut être écrit.', 'Installer script still present' => 'Le script d\'installation est toujours présent', 'Please make sure to delete the installer script "install.php" before continuing.' => 'Assurez vous de supprimer le fichier "install.php" avant de continuer.', 'An error occurred.' => 'Une erreur s\'est produite', @@ -102,6 +103,7 @@ $tr = array ( 'Wrong password.' => 'Mot de passe invalide.', 'Admin interface' => 'Interface d\'adminitration', 'Clean expired files' => 'Nettoie les fichiers périmés', + 'Clean old unfinished transferts' => 'Nettoie les vieux transferts inachevés', 'Clean' => 'Nettoyage', 'Search files by name' => 'Rechercher les fichiers par leur nom', 'Search' => 'Rechercher', @@ -147,5 +149,13 @@ $tr = array ( 'This will return "Ok" if succeded, "Error" otherwhise.' => 'Retourne "OK" en cas de succès, "Error" dans le cas contraire.', 'Get a generated scripts' => 'Récupérer un script généré', 'This will return brut text content of the code.' => 'Renvoie le code sous forme the texte brut.', + 'Initalize a asynchronous transfert' => 'Initialiser un transfert asynchrone', + 'The goal is to permit to transfert big file, chunk by chunk.' => 'Le but est de permettre de transférer de gros fichiers, morceaux par morceaux.', + 'Chunks of data must be sent in order.' => 'Chaque morceau doit être envoyé dans l\'ordre.', + 'First line is the asynchronous transfert reference and the second line the code to use in the next operation.' + => 'La première ligne correspond à la référence de transfert asynchrone, la seconde au code à utiliser dans la prochaine requette.', + 'Push data during asynchronous transfert' => 'Envoyer des données pendant un transfert asynchrone', + 'Returns the next code to use.' => 'Renvoie le prochain code à utiliser.', + 'Finalize asynchronous transfert' => 'Finalise un transfert asynchrone', ); ?> \ No newline at end of file diff --git a/lib/settings.php b/lib/settings.php index da00c63..74bf771 100644 --- a/lib/settings.php +++ b/lib/settings.php @@ -23,6 +23,7 @@ define ('JIRAFEAU_VERSION', '1.0'); /* Directories. */ define ('VAR_FILES', $cfg['var_root'] . 'files/'); define ('VAR_LINKS', $cfg['var_root'] . 'links/'); +define ('VAR_ASYNC', $cfg['var_root'] . 'async/'); /* Useful constants. */ if (!defined ('NL')) @@ -32,7 +33,7 @@ define ('JIRAFEAU_INFINITY', -1); define ('JIRAFEAU_MINUTE', 60); // 60 define ('JIRAFEAU_HOUR', 3600); // JIRAFEAU_MINUTE * 60 define ('JIRAFEAU_DAY', 86400); // JIRAFEAU_HOUR * 24 -define ('JIRAFEAU_WEEK', 604800); // JIRAFEAU_DAY * 7 -define ('JIRAFEAU_MONTH', 2419200); // JIRAFEAU_WEEK * 4 +define ('JIRAFEAU_WEEK', 604800); // JIRAFEAU_DAY * 7 +define ('JIRAFEAU_MONTH', 2419200); // JIRAFEAU_WEEK * 4 ?> diff --git a/script.php b/script.php index 6fd8626..ad354a5 100755 --- a/script.php +++ b/script.php @@ -135,6 +135,47 @@ if ($_SERVER['REQUEST_METHOD'] == "GET" && count ($_GET) == 0) foreach ($script_langages as $lang => $name) echo "$name: " . $web_root . "script.php?lang=$lang "; echo '

'; + + echo '

' . t('Initalize a asynchronous transfert') . ':

'; + echo '

'; + echo t('The goal is to permit to transfert big file, chunk by chunk.') . ' '; + echo t('Chunks of data must be sent in order.'); + echo '

'; + echo '

'; + echo t('Send a GET query to') . ': ' . $web_root . 'script.php?init_async
'; + echo '
'; + echo t('Parameters') . ':
'; + echo "filename=file_name.ext (" . t('Required') . ")
"; + echo "type=MIME_TYPE (" . t('Optional') . ")
"; + echo "time=[minute|hour|day|week|month|none] (" . t('Optional') . ', '. t('default: none') . ")
"; + echo "password=your_password (" . t('Optional') . ")
"; + echo "one_time_download=1 (" . t('Optional') . ")
"; + echo '

'; + echo '

' . t('This will return brut text content.') . ' ' . + t('First line is the asynchronous transfert reference and the second line the code to use in the next operation.') . '

'; + + echo '

' . t('Push data during asynchronous transfert') . ':

'; + echo '

'; + echo t('Send a GET query to') . ': ' . $web_root . 'script.php?push_async
'; + echo '
'; + echo t('Parameters') . ':
'; + echo "ref=async_reference (" . t('Required') . ")
"; + echo "data=data_chunk (" . t('Required') . ")
"; + echo "code=last_provided_code (" . t('Required') . ")
"; + echo '

'; + echo '

' . t('This will return brut text content.') . ' ' . + t('Returns the next code to use.') . '

'; + + echo '

' . t('Finalize asynchronous transfert') . ':

'; + echo '

'; + echo t('Send a GET query to') . ': ' . $web_root . 'script.php?end_async
'; + echo '
'; + echo t('Parameters') . ':
'; + echo "ref=async_reference (" . t('Required') . ")
"; + echo "code=last_provided_code (" . t('Required') . ")
"; + echo '

'; + echo '

' . t('This will return brut text content.') . ' ' . + t('First line is the download reference and the second line the delete code.') . '

'; echo '

'; require (JIRAFEAU_ROOT . 'lib/template/footer.php'); @@ -238,11 +279,19 @@ elseif (isset ($_GET['h'])) exit; } + /* Read file. */ header ('Content-Length: ' . $link['file_size']); header ('Content-Type: ' . $link['mime_type']); header ('Content-Disposition: attachment; filename="' . $link['file_name'] . '"'); - readfile (VAR_FILES . $p . $link['md5']); + + $r = fopen (VAR_FILES . $p . $link['md5'], 'r'); + while (!feof ($r)) + { + print fread ($r, 1024); + ob_flush(); + } + fclose ($r); if ($link['onetime'] == 'O') jirafeau_delete_link ($link_name); @@ -393,7 +442,75 @@ fi exit; } } +/* Initialize an asynchronous upload. */ +elseif (isset ($_GET['init_async'])) +{ + if (!isset ($_POST['filename'])) + { + echo "Error"; + exit; + } + + $type = ''; + if (isset ($_POST['type'])) + $type = $_POST['type']; + + $key = ''; + if (isset ($_POST['password'])) + $key = $_POST['password']; + + $time = time (); + if (!isset ($_POST['time'])) + $time = JIRAFEAU_INFINITY; + else + switch ($_POST['time']) + { + case 'minute': + $time += JIRAFEAU_MINUTE; + break; + case 'hour': + $time += JIRAFEAU_HOUR; + break; + case 'day': + $time += JIRAFEAU_DAY; + break; + case 'week': + $time += JIRAFEAU_WEEK; + break; + case 'month': + $time += JIRAFEAU_MONTH; + break; + default: + $time = JIRAFEAU_INFINITY; + break; + } + echo jirafeau_async_init ($_POST['filename'], + $type, + isset ($_POST['one_time_download']), + $key, + $time, + $_SERVER['REMOTE_ADDR']); +} +/* Continue an asynchronous upload. */ +elseif (isset ($_GET['push_async'])) +{ + if ((!isset ($_POST['ref'])) + || (!isset ($_FILES['data'])) + || (!isset ($_POST['code']))) + echo "Error"; + else + echo jirafeau_async_push ($_POST['ref'], $_FILES['data'], $_POST['code']); +} +/* Finalize an asynchronous upload. */ +elseif (isset ($_GET['end_async'])) +{ + if (!isset ($_POST['ref']) + || !isset ($_POST['code'])) + echo "Error"; + else + echo jirafeau_async_end ($_POST['ref'], $_POST['code']); +} else echo "Error"; exit; -?> \ No newline at end of file +?> -- 2.34.1