Merge pull request #4867 from owncloud/fixing-4546-master
Adding detection of aborted uploads for chunked uploads
This commit is contained in:
commit
c97b52090e
4 changed files with 75 additions and 19 deletions
18
lib/private/cache/file.php
vendored
18
lib/private/cache/file.php
vendored
|
@ -41,6 +41,24 @@ class File {
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the stored/cached data
|
||||
*
|
||||
* @param $key
|
||||
* @return int
|
||||
*/
|
||||
public function size($key) {
|
||||
$result = 0;
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
if ($this->hasKey($key)) {
|
||||
$storage = $this->getStorage();
|
||||
$result = $storage->filesize($key);
|
||||
}
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl=0) {
|
||||
$storage = $this->getStorage();
|
||||
$result = false;
|
||||
|
|
|
@ -71,7 +71,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
|||
$path = $this->path . '/' . $name;
|
||||
$node = new OC_Connector_Sabre_File($path);
|
||||
return $node->put($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,4 +228,5 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
|||
}
|
||||
return $props;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,23 +60,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
|
|||
|
||||
// chunked handling
|
||||
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
|
||||
|
||||
list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path);
|
||||
|
||||
$info = OC_FileChunking::decodeName($name);
|
||||
if (empty($info)) {
|
||||
throw new Sabre_DAV_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
$chunk_handler = new OC_FileChunking($info);
|
||||
$chunk_handler->store($info['index'], $data);
|
||||
if ($chunk_handler->isComplete()) {
|
||||
$newPath = $path . '/' . $info['name'];
|
||||
$chunk_handler->file_assemble($newPath);
|
||||
return $this->getETagPropertyForPath($newPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
return $this->createFileChunked($data);
|
||||
}
|
||||
|
||||
// mark file as partial while uploading (ignored by the scanner)
|
||||
|
@ -214,4 +198,37 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
|
|||
return \OC\Files\Filesystem::getMimeType($this->path);
|
||||
|
||||
}
|
||||
|
||||
private function createFileChunked($data)
|
||||
{
|
||||
list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path);
|
||||
|
||||
$info = OC_FileChunking::decodeName($name);
|
||||
if (empty($info)) {
|
||||
throw new Sabre_DAV_Exception_NotImplemented();
|
||||
}
|
||||
$chunk_handler = new OC_FileChunking($info);
|
||||
$bytesWritten = $chunk_handler->store($info['index'], $data);
|
||||
|
||||
//detect aborted upload
|
||||
if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) {
|
||||
if (isset($_SERVER['CONTENT_LENGTH'])) {
|
||||
$expected = $_SERVER['CONTENT_LENGTH'];
|
||||
if ($bytesWritten != $expected) {
|
||||
$chunk_handler->cleanup();
|
||||
throw new Sabre_DAV_Exception_BadRequest(
|
||||
'expected filesize ' . $expected . ' got ' . $bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($chunk_handler->isComplete()) {
|
||||
$newPath = $path . '/' . $info['name'];
|
||||
$chunk_handler->file_assemble($newPath);
|
||||
return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,10 +34,19 @@ class OC_FileChunking {
|
|||
return $this->cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given $data under the given $key - the number of stored bytes is returned
|
||||
*
|
||||
* @param $index
|
||||
* @param $data
|
||||
* @return int
|
||||
*/
|
||||
public function store($index, $data) {
|
||||
$cache = $this->getCache();
|
||||
$name = $this->getPrefix().$index;
|
||||
$cache->set($name, $data);
|
||||
|
||||
return $cache->size($name);
|
||||
}
|
||||
|
||||
public function isComplete() {
|
||||
|
@ -58,12 +67,24 @@ class OC_FileChunking {
|
|||
$count = 0;
|
||||
for($i=0; $i < $this->info['chunkcount']; $i++) {
|
||||
$chunk = $cache->get($prefix.$i);
|
||||
$cache->remove($prefix.$i);
|
||||
$count += fwrite($f, $chunk);
|
||||
}
|
||||
|
||||
$this->cleanup();
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all chunks which belong to this transmission
|
||||
*/
|
||||
public function cleanup() {
|
||||
$cache = $this->getCache();
|
||||
$prefix = $this->getPrefix();
|
||||
for($i=0; $i < $this->info['chunkcount']; $i++) {
|
||||
$cache->remove($prefix.$i);
|
||||
}
|
||||
}
|
||||
|
||||
public function signature_split($orgfile, $input) {
|
||||
$info = unpack('n', fread($input, 2));
|
||||
$blocksize = $info[1];
|
||||
|
|
Loading…
Reference in a new issue