* This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ /** * Class OC_Connector_Sabre_AbortedUploadDetectionPlugin * * This plugin will verify if the uploaded data has been stored completely. * This is done by comparing the content length of the request with the file size on storage. */ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPlugin { /** * Reference to main server object * * @var Sabre_DAV_Server */ private $server; /** * is kept public to allow overwrite for unit testing * * @var \OC\Files\View */ public $fileView; /** * This initializes the plugin. * * This function is called by Sabre_DAV_Server, after * addPlugin is called. * * This method should set up the requires event subscriptions. * * @param Sabre_DAV_Server $server * @return void */ public function initialize(Sabre_DAV_Server $server) { $this->server = $server; $server->subscribeEvent('afterCreateFile', array($this, 'afterCreateFile'), 10); $server->subscribeEvent('afterWriteContent', array($this, 'afterWriteContent'), 10); } function afterCreateFile($path, Sabre_DAV_ICollection $parent) { $this->verifyContentLength($path); } function afterWriteContent($path, Sabre_DAV_IFile $node) { $this->verifyContentLength($path); } function verifyContentLength($filePath) { // ownCloud chunked upload will be handled in it's own plugin $chunkHeader = $this->server->httpRequest->getHeader('OC-Chunked'); if ($chunkHeader) { return; } // compare expected and actual size $expected = $this->getLength(); $actual = $this->getFileView()->filesize($filePath); if ($actual != $expected) { $this->getFileView()->unlink($filePath); throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual); } } /** * @return string */ public function getLength() { $req = $this->server->httpRequest; $length = $req->getHeader('X-Expected-Entity-Length'); if (!$length) { $length = $req->getHeader('Content-Length'); } return $length; } /** * @return \OC\Files\View */ public function getFileView() { if (is_null($this->fileView)) { // initialize fileView $this->fileView = \OC\Files\Filesystem::getView(); } return $this->fileView; } }