Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Nextcloud
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TeDomum
Nextcloud
Commits
c8fa1fd6
Commit
c8fa1fd6
authored
11 years ago
by
Andreas Fischer
Browse files
Options
Downloads
Patches
Plain Diff
Refactor Large File handling code.
parent
3f8f8027
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
lib/private/files/storage/local.php
+8
-90
8 additions, 90 deletions
lib/private/files/storage/local.php
lib/private/files/storage/mappedlocal.php
+12
-41
12 additions, 41 deletions
lib/private/files/storage/mappedlocal.php
lib/private/largefilehelper.php
+103
-0
103 additions, 0 deletions
lib/private/largefilehelper.php
with
123 additions
and
131 deletions
lib/private/files/storage/local.php
+
8
−
90
View file @
c8fa1fd6
...
@@ -89,9 +89,8 @@ if (\OC_Util::runningOnWindows()) {
...
@@ -89,9 +89,8 @@ if (\OC_Util::runningOnWindows()) {
public
function
stat
(
$path
)
{
public
function
stat
(
$path
)
{
$fullPath
=
$this
->
datadir
.
$path
;
$fullPath
=
$this
->
datadir
.
$path
;
$statResult
=
stat
(
$fullPath
);
$statResult
=
stat
(
$fullPath
);
if
(
PHP_INT_SIZE
===
4
)
{
$filesize
=
self
::
getFileSizeWithTricks
(
$fullPath
);
$filesize
=
$this
->
filesize
(
$path
);
if
(
!
is_null
(
$filesize
))
{
$statResult
[
'size'
]
=
$filesize
;
$statResult
[
'size'
]
=
$filesize
;
$statResult
[
7
]
=
$filesize
;
$statResult
[
7
]
=
$filesize
;
}
}
...
@@ -109,16 +108,16 @@ if (\OC_Util::runningOnWindows()) {
...
@@ -109,16 +108,16 @@ if (\OC_Util::runningOnWindows()) {
public
function
filesize
(
$path
)
{
public
function
filesize
(
$path
)
{
if
(
$this
->
is_dir
(
$path
))
{
if
(
$this
->
is_dir
(
$path
))
{
return
0
;
return
0
;
}
else
{
}
$fullPath
=
$this
->
datadir
.
$path
;
$fullPath
=
$this
->
datadir
.
$path
;
if
(
PHP_INT_SIZE
===
4
)
{
$filesize
=
self
::
getFileSizeWithTricks
(
$fullPath
);
$helper
=
new
\OC\LargeFileHelper
;
$filesize
=
$helper
->
getFilesize
(
$fullPath
);
if
(
!
is_null
(
$filesize
))
{
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
return
$filesize
;
}
}
return
filesize
(
$fullPath
);
}
}
return
filesize
(
$fullPath
);
}
}
public
function
isReadable
(
$path
)
{
public
function
isReadable
(
$path
)
{
...
@@ -221,87 +220,6 @@ if (\OC_Util::runningOnWindows()) {
...
@@ -221,87 +220,6 @@ if (\OC_Util::runningOnWindows()) {
return
$return
;
return
$return
;
}
}
/**
* @brief Tries to get the filesize via various workarounds if necessary.
* @param string $fullPath
* @return mixed Number of bytes on success and workaround necessary, null otherwise.
*/
private
static
function
getFileSizeWithTricks
(
$fullPath
)
{
if
(
PHP_INT_SIZE
===
4
)
{
// filesize() and stat() are unreliable on 32bit systems
// for big files.
// In some cases they cause an E_WARNING and return false,
// in some other cases they silently wrap around at 2^32,
// i.e. e.g. report 674347008 bytes instead of 4969314304.
$filesize
=
self
::
getFileSizeFromCurl
(
$fullPath
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
$filesize
=
self
::
getFileSizeFromOS
(
$fullPath
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
}
return
null
;
}
/**
* @brief Tries to get the filesize via a CURL HEAD request.
* @param string $fullPath
* @return mixed Number of bytes on success, null otherwise.
*/
private
static
function
getFileSizeFromCurl
(
$fullPath
)
{
if
(
function_exists
(
'curl_init'
))
{
$ch
=
curl_init
(
"file://
$fullPath
"
);
curl_setopt
(
$ch
,
CURLOPT_NOBODY
,
true
);
curl_setopt
(
$ch
,
CURLOPT_RETURNTRANSFER
,
true
);
curl_setopt
(
$ch
,
CURLOPT_HEADER
,
true
);
$data
=
curl_exec
(
$ch
);
curl_close
(
$ch
);
if
(
$data
!==
false
)
{
$matches
=
array
();
preg_match
(
'/Content-Length: (\d+)/'
,
$data
,
$matches
);
if
(
isset
(
$matches
[
1
]))
{
return
0
+
$matches
[
1
];
}
}
}
return
null
;
}
/**
* @brief Tries to get the filesize via COM and exec().
* @param string $fullPath
* @return mixed Number of bytes on success, null otherwise.
*/
private
static
function
getFileSizeFromOS
(
$fullPath
)
{
$name
=
strtolower
(
php_uname
(
's'
));
// Windows OS: we use COM to access the filesystem
if
(
strpos
(
$name
,
'win'
)
!==
false
)
{
if
(
class_exists
(
'COM'
))
{
$fsobj
=
new
\COM
(
"Scripting.FileSystemObject"
);
$f
=
$fsobj
->
GetFile
(
$fullPath
);
return
$f
->
Size
;
}
}
else
if
(
strpos
(
$name
,
'bsd'
)
!==
false
)
{
if
(
\OC_Helper
::
is_function_enabled
(
'exec'
))
{
return
0
+
exec
(
'stat -f %z '
.
escapeshellarg
(
$fullPath
));
}
}
else
if
(
strpos
(
$name
,
'linux'
)
!==
false
)
{
if
(
\OC_Helper
::
is_function_enabled
(
'exec'
))
{
return
0
+
exec
(
'stat -c %s '
.
escapeshellarg
(
$fullPath
));
}
}
else
{
\OC_Log
::
write
(
'core'
,
'Unable to determine file size of "'
.
$fullPath
.
'". Unknown OS: '
.
$name
,
\OC_Log
::
ERROR
);
}
return
null
;
}
public
function
hash
(
$type
,
$path
,
$raw
=
false
)
{
public
function
hash
(
$type
,
$path
,
$raw
=
false
)
{
return
hash_file
(
$type
,
$this
->
datadir
.
$path
,
$raw
);
return
hash_file
(
$type
,
$this
->
datadir
.
$path
,
$raw
);
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/private/files/storage/mappedlocal.php
+
12
−
41
View file @
c8fa1fd6
...
@@ -111,11 +111,10 @@ class MappedLocal extends \OC\Files\Storage\Common {
...
@@ -111,11 +111,10 @@ class MappedLocal extends \OC\Files\Storage\Common {
public
function
stat
(
$path
)
{
public
function
stat
(
$path
)
{
$fullPath
=
$this
->
buildPath
(
$path
);
$fullPath
=
$this
->
buildPath
(
$path
);
$statResult
=
stat
(
$fullPath
);
$statResult
=
stat
(
$fullPath
);
if
(
PHP_INT_SIZE
===
4
)
{
if
(
$statResult
[
'size'
]
<
0
)
{
$filesize
=
$this
->
filesize
(
$path
);
$size
=
self
::
getFileSizeFromOS
(
$fullPath
);
$statResult
[
'size'
]
=
$filesize
;
$statResult
[
'size'
]
=
$size
;
$statResult
[
7
]
=
$filesize
;
$statResult
[
7
]
=
$size
;
}
}
return
$statResult
;
return
$statResult
;
}
}
...
@@ -131,15 +130,16 @@ class MappedLocal extends \OC\Files\Storage\Common {
...
@@ -131,15 +130,16 @@ class MappedLocal extends \OC\Files\Storage\Common {
public
function
filesize
(
$path
)
{
public
function
filesize
(
$path
)
{
if
(
$this
->
is_dir
(
$path
))
{
if
(
$this
->
is_dir
(
$path
))
{
return
0
;
return
0
;
}
else
{
}
$fullPath
=
$this
->
buildPath
(
$path
);
$fullPath
=
$this
->
buildPath
(
$path
);
$fileSize
=
filesize
(
$fullPath
);
if
(
PHP_INT_SIZE
===
4
)
{
if
(
$fileSize
<
0
)
{
$helper
=
new
\OC\LargeFileHelper
;
return
self
::
getFileSizeFromOS
(
$fullPath
);
$filesize
=
$helper
->
getFilesize
(
$fullPath
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
}
return
$fileSize
;
}
}
return
filesize
(
$fullPath
);
}
}
public
function
isReadable
(
$path
)
{
public
function
isReadable
(
$path
)
{
...
@@ -294,35 +294,6 @@ class MappedLocal extends \OC\Files\Storage\Common {
...
@@ -294,35 +294,6 @@ class MappedLocal extends \OC\Files\Storage\Common {
return
$return
;
return
$return
;
}
}
/**
* @param string $fullPath
*/
private
static
function
getFileSizeFromOS
(
$fullPath
)
{
$name
=
strtolower
(
php_uname
(
's'
));
// Windows OS: we use COM to access the filesystem
if
(
strpos
(
$name
,
'win'
)
!==
false
)
{
if
(
class_exists
(
'COM'
))
{
$fsobj
=
new
\COM
(
"Scripting.FileSystemObject"
);
$f
=
$fsobj
->
GetFile
(
$fullPath
);
return
$f
->
Size
;
}
}
else
if
(
strpos
(
$name
,
'bsd'
)
!==
false
)
{
if
(
\OC_Helper
::
is_function_enabled
(
'exec'
))
{
return
(
float
)
exec
(
'stat -f %z '
.
escapeshellarg
(
$fullPath
));
}
}
else
if
(
strpos
(
$name
,
'linux'
)
!==
false
)
{
if
(
\OC_Helper
::
is_function_enabled
(
'exec'
))
{
return
(
float
)
exec
(
'stat -c %s '
.
escapeshellarg
(
$fullPath
));
}
}
else
{
\OC_Log
::
write
(
'core'
,
'Unable to determine file size of "'
.
$fullPath
.
'". Unknown OS: '
.
$name
,
\OC_Log
::
ERROR
);
}
return
0
;
}
public
function
hash
(
$type
,
$path
,
$raw
=
false
)
{
public
function
hash
(
$type
,
$path
,
$raw
=
false
)
{
return
hash_file
(
$type
,
$this
->
buildPath
(
$path
),
$raw
);
return
hash_file
(
$type
,
$this
->
buildPath
(
$path
),
$raw
);
}
}
...
...
This diff is collapsed.
Click to expand it.
lib/private/largefilehelper.php
0 → 100644
+
103
−
0
View file @
c8fa1fd6
<?php
/**
* Copyright (c) 2014 Andreas Fischer <bantu@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace
OC
;
/**
* Helper class for large files on 32-bit platforms.
*/
class
LargeFileHelper
{
/**
* @brief Tries to get the filesize of a file via various workarounds that
* even work for large files on 32-bit platforms.
*
* @param string $filename Path to the file.
*
* @return null|int|float Number of bytes as number (float or int) or
* null on failure.
*/
public
function
getFilesize
(
$filename
)
{
$filesize
=
$this
->
getFilesizeViaCurl
(
$filename
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
$filesize
=
$this
->
getFilesizeViaCOM
(
$filename
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
$filesize
=
$this
->
getFilesizeViaExec
(
$filename
);
if
(
!
is_null
(
$filesize
))
{
return
$filesize
;
}
return
null
;
}
/**
* @brief Tries to get the filesize of a file via a CURL HEAD request.
*
* @param string $filename Path to the file.
*
* @return null|int|float Number of bytes as number (float or int) or
* null on failure.
*/
public
function
getFilesizeViaCurl
(
$filename
)
{
if
(
function_exists
(
'curl_init'
))
{
$ch
=
curl_init
(
"file://
$filename
"
);
curl_setopt
(
$ch
,
CURLOPT_NOBODY
,
true
);
curl_setopt
(
$ch
,
CURLOPT_RETURNTRANSFER
,
true
);
curl_setopt
(
$ch
,
CURLOPT_HEADER
,
true
);
$data
=
curl_exec
(
$ch
);
curl_close
(
$ch
);
if
(
$data
!==
false
)
{
$matches
=
array
();
preg_match
(
'/Content-Length: (\d+)/'
,
$data
,
$matches
);
if
(
isset
(
$matches
[
1
]))
{
return
0
+
$matches
[
1
];
}
}
}
return
null
;
}
/**
* @brief Tries to get the filesize of a file via the Windows DOM extension.
*
* @param string $filename Path to the file.
*
* @return null|int|float Number of bytes as number (float or int) or
* null on failure.
*/
public
function
getFilesizeViaCOM
(
$filename
)
{
if
(
class_exists
(
'COM'
))
{
$fsobj
=
new
\COM
(
"Scripting.FileSystemObject"
);
$file
=
$fsobj
->
GetFile
(
$filename
);
return
0
+
$file
->
Size
;
}
return
null
;
}
/**
* @brief Tries to get the filesize of a file via an exec() call.
*
* @param string $filename Path to the file.
*
* @return null|int|float Number of bytes as number (float or int) or
* null on failure.
*/
public
function
getFilesizeViaExec
(
$filename
)
{
if
(
\OC_Helper
::
is_function_enabled
(
'exec'
))
{
$os
=
strtolower
(
php_uname
(
's'
));
if
(
strpos
(
$os
,
'linux'
)
!==
false
)
{
return
0
+
exec
(
'stat -c %s '
.
escapeshellarg
(
$filename
));
}
else
if
(
strpos
(
$os
,
'bsd'
)
!==
false
)
{
return
0
+
exec
(
'stat -f %z '
.
escapeshellarg
(
$filename
));
}
}
return
null
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment