Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2013-10-31 15:27:04 +0400
committerThomas Müller <thomas.mueller@tmit.eu>2013-10-31 15:27:04 +0400
commit817a10b465ca04148cbcb5d5a2fb1c558ad1415e (patch)
tree1a21070f2c788190b7880de2ece4bb74f1c10425 /lib
parent640a1f28feb18acac8126f7eb2004ac85c416faf (diff)
parente7fb6be72a3ef548a068f83ac2f4f45ee36c2588 (diff)
Merge pull request #5327 from owncloud/backport-4867-stable5
[stable5] Adding detection of aborted uploads for chunked uploads
Diffstat (limited to 'lib')
-rw-r--r--lib/cache/file.php18
-rw-r--r--lib/connector/sabre/directory.php40
-rw-r--r--lib/filechunking.php33
3 files changed, 82 insertions, 9 deletions
diff --git a/lib/cache/file.php b/lib/cache/file.php
index 361138e4736..eed2637c981 100644
--- a/lib/cache/file.php
+++ b/lib/cache/file.php
@@ -40,6 +40,24 @@ class OC_Cache_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;
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php
index 96b9cd06d5b..3cccf6ef3d0 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/connector/sabre/directory.php
@@ -61,13 +61,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
throw new \Sabre_DAV_Exception_Forbidden();
}
- $chunk_handler = new OC_FileChunking($info);
- $chunk_handler->store($info['index'], $data);
- if ($chunk_handler->isComplete()) {
- $newPath = $this->path . '/' . $info['name'];
- $chunk_handler->file_assemble($newPath);
- return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
- }
+ return $this->createFileChunked($name, $data);
} else {
if (!\OC\Files\Filesystem::isCreatable($this->path)) {
@@ -264,7 +258,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* If the array is empty, all properties should be returned
*
* @param array $properties
- * @return void
+ * @return array
*/
public function getProperties($properties) {
$props = parent::getProperties($properties);
@@ -274,4 +268,34 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
}
return $props;
}
+
+ private function createFileChunked($name, $data)
+ {
+ $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->remove($info['index']);
+ throw new Sabre_DAV_Exception_BadRequest(
+ 'expected filesize ' . $expected . ' got ' . $bytesWritten);
+ }
+ }
+ }
+
+ if ($chunk_handler->isComplete()) {
+ $newPath = $this->path . '/' . $info['name'];
+ $chunk_handler->file_assemble($newPath);
+ return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
+ }
+
+ return null;
+ }
}
diff --git a/lib/filechunking.php b/lib/filechunking.php
index e6d69273a44..bee6f702298 100644
--- a/lib/filechunking.php
+++ b/lib/filechunking.php
@@ -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,34 @@ 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);
+ }
+ }
+
+ /**
+ * Removes one specific chunk
+ * @param $index
+ */
+ public function remove($index) {
+ $cache = $this->getCache();
+ $prefix = $this->getPrefix();
+ $cache->remove($prefix.$index);
+ }
+
public function signature_split($orgfile, $input) {
$info = unpack('n', fread($input, 2));
$blocksize = $info[1];