forked from extern/egroupware
changed token-size to 32 char (more then plenty), only use tokens containing no special url chars (/#), and do not copy files to tmp-dir in vfs, if identical files already there to use
This commit is contained in:
parent
65a9f8e584
commit
6955afccc8
@ -24,8 +24,11 @@ class egw_sharing
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Length of base64 encoded token (real length is only 3/4 of it)
|
* Length of base64 encoded token (real length is only 3/4 of it)
|
||||||
|
*
|
||||||
|
* Dropbox uses just 15 chars (letters/numbers 5-6 bit), php sessions use 32 chars (hex = 4bits),
|
||||||
|
* so 32 chars of base64 = 6bits should be plenty.
|
||||||
*/
|
*/
|
||||||
const TOKEN_LENGTH = 64;
|
const TOKEN_LENGTH = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of table used for storing tokens
|
* Name of table used for storing tokens
|
||||||
@ -237,9 +240,12 @@ class egw_sharing
|
|||||||
public static function token()
|
public static function token()
|
||||||
{
|
{
|
||||||
// generate random token (using oppenssl if available otherwise mt_rand based auth::randomstring)
|
// generate random token (using oppenssl if available otherwise mt_rand based auth::randomstring)
|
||||||
$token = function_exists('openssl_random_pseudo_bytes') ?
|
do {
|
||||||
base64_encode(openssl_random_pseudo_bytes(3*self::TOKEN_LENGTH/4)) :
|
$token = function_exists('openssl_random_pseudo_bytes') ?
|
||||||
auth::randomstring(self::TOKEN_LENGTH);
|
base64_encode(openssl_random_pseudo_bytes(3*self::TOKEN_LENGTH/4)) :
|
||||||
|
auth::randomstring(self::TOKEN_LENGTH);
|
||||||
|
// base64 can contain chars not allowed in our vfs-urls eg. / or #
|
||||||
|
} while ($token != egw_vfs::encodePathComponent($token));
|
||||||
|
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
@ -276,7 +282,7 @@ class egw_sharing
|
|||||||
$path = 'vfs://default'.($path[0] == '/' ? '' : '/').$path;
|
$path = 'vfs://default'.($path[0] == '/' ? '' : '/').$path;
|
||||||
}
|
}
|
||||||
// check if file exists and is readable
|
// check if file exists and is readable
|
||||||
if (!file_exists($path) || is_readable($path))
|
if (!file_exists($path) || !is_readable($path))
|
||||||
{
|
{
|
||||||
throw new egw_exception_not_found("'$path' NOT found!");
|
throw new egw_exception_not_found("'$path' NOT found!");
|
||||||
}
|
}
|
||||||
@ -323,7 +329,9 @@ class egw_sharing
|
|||||||
$tmp_file = egw_vfs::concat($user_tmp, ($n?$n.'.':'').egw_vfs::basename($name));
|
$tmp_file = egw_vfs::concat($user_tmp, ($n?$n.'.':'').egw_vfs::basename($name));
|
||||||
}
|
}
|
||||||
while(!(is_dir($path) && egw_vfs::mkdir($tmp_file) ||
|
while(!(is_dir($path) && egw_vfs::mkdir($tmp_file) ||
|
||||||
!is_dir($path) && ($fp = egw_vfs::fopen($tmp_file, 'x'))) && $n++ < 100);
|
!is_dir($path) && (!egw_vfs::file_exists($tmp_file) && ($fp = egw_vfs::fopen($tmp_file, 'x')) ||
|
||||||
|
// do not copy identical files again to users tmp dir, just re-use them
|
||||||
|
egw_vfs::file_exists($tmp_file) && egw_vfs::compare(egw_vfs::PREFIX.$tmp_file, $path))) && $n++ < 100);
|
||||||
|
|
||||||
if ($n >= 100)
|
if ($n >= 100)
|
||||||
{
|
{
|
||||||
@ -340,6 +348,13 @@ class egw_sharing
|
|||||||
$path2tmp[$path] = $tmp_file;
|
$path2tmp[$path] = $tmp_file;
|
||||||
|
|
||||||
$path = $tmp_file;
|
$path = $tmp_file;
|
||||||
|
|
||||||
|
// if not already installed, install periodic cleanup of tmp files
|
||||||
|
$async = new asyncservice();
|
||||||
|
if (!$async->read('egw_sharing-tmp-cleanup'))
|
||||||
|
{
|
||||||
|
$async->set_timer(array('day' => 28),'egw_sharing-tmp_cleanup','egw_sharing::tmp_cleanup',null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
@ -366,6 +381,28 @@ class egw_sharing
|
|||||||
return $share;
|
return $share;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Periodic (monthly) cleanup of temp. sharing files
|
||||||
|
*/
|
||||||
|
public static function tmp_cleanup()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
egw_vfs::$is_root = true;
|
||||||
|
/* not yet ready
|
||||||
|
egw_vfs::find('/home', array(
|
||||||
|
'path_preg' => '|^/home/[^/]+/.tmp',
|
||||||
|
'maxdepth' => 3,
|
||||||
|
), function($path, $stat)
|
||||||
|
{
|
||||||
|
error_log(__METHOD__."() path=$path");
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
unset($e);
|
||||||
|
}
|
||||||
|
egw_vfs::$is_root = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate link from share or share-token
|
* Generate link from share or share-token
|
||||||
*
|
*
|
||||||
|
@ -2005,6 +2005,36 @@ class egw_vfs extends vfs_stream_wrapper
|
|||||||
if (self::LOG_LEVEL > 1 || !$ret && self::LOG_LEVEL) error_log(__METHOD__."($tmp_name, $target, ".array2string($props).") returning ".array2string($ret));
|
if (self::LOG_LEVEL > 1 || !$ret && self::LOG_LEVEL) error_log(__METHOD__."($tmp_name, $target, ".array2string($props).") returning ".array2string($ret));
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two files from vfs or local file-system for identical content
|
||||||
|
*
|
||||||
|
* VFS files must use URL, to be able to distinguish them eg. from temp. files!
|
||||||
|
*
|
||||||
|
* @param string $file1 vfs-url or local path, eg. /tmp/some-file.txt or vfs://default/home/user/some-file.txt
|
||||||
|
* @param string $file2 -- " --
|
||||||
|
* @return boolean true: if files are identical, false: if not or file not found
|
||||||
|
*/
|
||||||
|
public static function compare($file1, $file2)
|
||||||
|
{
|
||||||
|
if (filesize($file1) != filesize($file2) ||
|
||||||
|
!($fp1 = fopen($file1, 'r')) || !($fp2 = fopen($file2, 'r')))
|
||||||
|
{
|
||||||
|
//error_log(__METHOD__."($file1, $file2) returning FALSE (different size)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (($read1 = fread($fp1, 8192)) !== false &&
|
||||||
|
($read2 = fread($fp2, 8192)) !== false &&
|
||||||
|
$read1 === $read2 && !feof($fp1) && !feof($fp2))
|
||||||
|
{
|
||||||
|
// just loop until we find a difference
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($fp1);
|
||||||
|
fclose($fp2);
|
||||||
|
//error_log(__METHOD__."($file1, $file2) returning ".array2string($read1 === $read2)." (content differs)");
|
||||||
|
return $read1 === $read2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
egw_vfs::init_static();
|
egw_vfs::init_static();
|
||||||
|
Loading…
Reference in New Issue
Block a user