Exemple #1
0
 /**
  * Updates the data
  *
  * The data argument is a readable stream resource.
  *
  * After a succesful put operation, you may choose to return an ETag. The
  * etag must always be surrounded by double-quotes. These quotes must
  * appear in the actual string you're returning.
  *
  * Clients may use the ETag from a PUT request to later on make sure that
  * when they update the file, the contents haven't changed in the mean
  * time.
  *
  * If you don't plan to store the file byte-by-byte, and you return a
  * different object on a subsequent GET you are strongly recommended to not
  * return an ETag, and just return null.
  *
  * @param resource $data
  * @throws Sabre_DAV_Exception_Forbidden
  * @return string|null
  */
 public function put($data)
 {
     if (!\OC\Files\Filesystem::isUpdatable($this->path)) {
         throw new \Sabre_DAV_Exception_Forbidden();
     }
     // mark file as partial while uploading (ignored by the scanner)
     $partpath = $this->path . '.part';
     \OC\Files\Filesystem::file_put_contents($partpath, $data);
     //detect aborted upload
     if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
         if (isset($_SERVER['CONTENT_LENGTH'])) {
             $expected = $_SERVER['CONTENT_LENGTH'];
             $actual = \OC\Files\Filesystem::filesize($partpath);
             if ($actual != $expected) {
                 \OC\Files\Filesystem::unlink($partpath);
                 throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual);
             }
         }
     }
     // rename to correct path
     \OC\Files\Filesystem::rename($partpath, $this->path);
     //allow sync clients to send the mtime along in a header
     $mtime = OC_Request::hasModificationTime();
     if ($mtime !== false) {
         if (\OC\Files\Filesystem::touch($this->path, $mtime)) {
             header('X-OC-MTime: accepted');
         }
     }
     return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path);
 }
Exemple #2
0
 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->remove($info['index']);
                 throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $bytesWritten);
             }
         }
     }
     if ($chunk_handler->isComplete()) {
         // we first assembly the target file as a part file
         $partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part';
         $chunk_handler->file_assemble($partFile);
         // here is the final atomic rename
         $fs = $this->getFS();
         $targetPath = $path . '/' . $info['name'];
         $renameOkay = $fs->rename($partFile, $targetPath);
         $fileExists = $fs->file_exists($targetPath);
         if ($renameOkay === false || $fileExists === false) {
             \OC_Log::write('webdav', '\\OC\\Files\\Filesystem::rename() failed', \OC_Log::ERROR);
             // only delete if an error occurred and the target file was already created
             if ($fileExists) {
                 $fs->unlink($targetPath);
             }
             throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks');
         }
         // allow sync clients to send the mtime along in a header
         $mtime = OC_Request::hasModificationTime();
         if ($mtime !== false) {
             if ($fs->touch($targetPath, $mtime)) {
                 header('X-OC-MTime: accepted');
             }
         }
         return OC_Connector_Sabre_Node::getETagPropertyForPath($targetPath);
     }
     return null;
 }
Exemple #3
0
 /**
  * Returns a list of properties for this nodes.;
  *
  * The properties list is a list of propertynames the client requested,
  * encoded as xmlnamespace#tagName, for example:
  * http://www.example.org/namespace#author
  * If the array is empty, all properties should be returned
  *
  * @param array $properties
  * @return array
  */
 public function getProperties($properties)
 {
     $props = parent::getProperties($properties);
     if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) {
         $props[self::GETETAG_PROPERTYNAME] = $this->info->getEtag();
     }
     return $props;
 }
 /**
  * Returns a list of properties for this nodes.;
  *
  * The properties list is a list of propertynames the client requested,
  * encoded as xmlnamespace#tagName, for example:
  * http://www.example.org/namespace#author
  * If the array is empty, all properties should be returned
  *
  * @param array $properties
  * @return array
  */
 public function getProperties($properties)
 {
     $props = parent::getProperties($properties);
     if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) {
         $props[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path);
     }
     return $props;
 }
Exemple #5
0
 /**
  * Updates the data
  *
  * The data argument is a readable stream resource.
  *
  * After a succesful put operation, you may choose to return an ETag. The
  * etag must always be surrounded by double-quotes. These quotes must
  * appear in the actual string you're returning.
  *
  * Clients may use the ETag from a PUT request to later on make sure that
  * when they update the file, the contents haven't changed in the mean
  * time.
  *
  * If you don't plan to store the file byte-by-byte, and you return a
  * different object on a subsequent GET you are strongly recommended to not
  * return an ETag, and just return null.
  *
  * @param resource $data
  * @return string|null
  */
 public function put($data)
 {
     OC_Filesystem::file_put_contents($this->path, $data);
     return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path);
 }
Exemple #6
0
 public static function removeETagHook($params, $root = false)
 {
     if (isset($params['path'])) {
         $path = $params['path'];
     } else {
         $path = $params['oldpath'];
     }
     if ($root) {
         // reduce path to the required part of it (no 'username/files')
         $fakeRootView = new OC_FilesystemView($root);
         $count = 1;
         $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count);
     }
     $path = self::normalizePath($path);
     OC_Connector_Sabre_Node::removeETagPropertyForPath($path);
 }