diff options
author | Bart Visscher <bartv@thisnet.nl> | 2012-08-03 15:58:17 +0200 |
---|---|---|
committer | Bart Visscher <bartv@thisnet.nl> | 2012-08-03 15:58:17 +0200 |
commit | e36e00dc00eaecddd184d27a61acdefe880f6336 (patch) | |
tree | d542c025b0378dab9dcd7598d7172918684c9879 /lib | |
parent | c5d5ca88a87dcad5df8af77fd4c6c9bc6ba2282e (diff) | |
parent | 896d27de36dd26515f30fa3b0748c9c6089600af (diff) | |
download | nextcloud-server-e36e00dc00eaecddd184d27a61acdefe880f6336.tar.gz nextcloud-server-e36e00dc00eaecddd184d27a61acdefe880f6336.zip |
Merge branch 'chunked_upload'
Diffstat (limited to 'lib')
-rw-r--r-- | lib/connector/sabre/directory.php | 20 | ||||
-rw-r--r-- | lib/filechunking.php | 94 |
2 files changed, 110 insertions, 4 deletions
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 7f8434c7151..09c65f19b80 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -48,11 +48,23 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return null|string */ public function createFile($name, $data = null) { + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + $info = OC_FileChunking::decodeName($name); + $chunk_handler = new OC_FileChunking($info); + $chunk_handler->store($info['index'], $data); + if ($chunk_handler->isComplete()) { + $newPath = $this->path . '/' . $info['name']; + $f = OC_Filesystem::fopen($newPath, 'w'); + $chunk_handler->assemble($f); + return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); + } + } else { + $newPath = $this->path . '/' . $name; + OC_Filesystem::file_put_contents($newPath,$data); + return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); + } - $newPath = $this->path . '/' . $name; - OC_Filesystem::file_put_contents($newPath,$data); - - return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); + return null; } /** diff --git a/lib/filechunking.php b/lib/filechunking.php new file mode 100644 index 00000000000..d03af226d8b --- /dev/null +++ b/lib/filechunking.php @@ -0,0 +1,94 @@ +<?php +/** + * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + + +class OC_FileChunking { + protected $info; + protected $cache; + + static public function decodeName($name) { + preg_match('/(?P<name>.*)-chunking-(?P<transferid>\d+)-(?P<chunkcount>\d+)-(?P<index>\d+)/', $name, $matches); + return $matches; + } + + public function __construct($info) { + $this->info = $info; + } + + public function getPrefix() { + $name = $this->info['name']; + $transferid = $this->info['transferid']; + + return $name.'-chunking-'.$transferid.'-'; + } + + protected function getCache() { + if (!isset($this->cache)) { + $this->cache = new OC_Cache_File(); + } + return $this->cache; + } + + public function store($index, $data) { + $cache = $this->getCache(); + $name = $this->getPrefix().$index; + $cache->set($name, $data); + } + + public function isComplete() { + $prefix = $this->getPrefix(); + $parts = 0; + $cache = $this->getCache(); + for($i=0; $i < $this->info['chunkcount']; $i++) { + if ($cache->hasKey($prefix.$i)) { + $parts ++; + } + } + return $parts == $this->info['chunkcount']; + } + + public function assemble($f) { + $cache = $this->getCache(); + $prefix = $this->getPrefix(); + for($i=0; $i < $this->info['chunkcount']; $i++) { + $chunk = $cache->get($prefix.$i); + $cache->remove($prefix.$i); + fwrite($f,$chunk); + } + fclose($f); + } + + public function signature_split($orgfile, $input) { + $info = unpack('n', fread($input, 2)); + $blocksize = $info[1]; + $this->info['transferid'] = mt_rand(); + $count = 0; + $needed = array(); + $cache = $this->getCache(); + $prefix = $this->getPrefix(); + while (!feof($orgfile)) { + $new_md5 = fread($input, 16); + if (feof($input)) { + break; + } + $data = fread($orgfile, $blocksize); + $org_md5 = md5($data, true); + if ($org_md5 == $new_md5) { + $cache->set($prefix.$count, $data); + } else { + $needed[] = $count; + } + $count++; + } + return array( + 'transferid' => $this->info['transferid'], + 'needed' => $needed, + 'count' => $count, + ); + } +} |