Skip to content

Commit

Permalink
Add ETag support to the Sabre file connector.
Browse files Browse the repository at this point in the history
This is based on the md5 of the file, can be changed later
  • Loading branch information
bartv2 committed Jul 20, 2012
1 parent 53bdb04 commit cdd9ffc
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
22 changes: 19 additions & 3 deletions lib/connector/sabre/directory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,33 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
/**
* Creates a new file in the directory
*
* data is a readable stream resource
* Data will either be supplied as a stream resource, or in certain cases
* as a string. Keep in mind that you may have to support either.
*
* After succesful creation of the file, you may choose to return the ETag
* of the new file here.
*
* The returned ETag must be surrounded by double-quotes (The quotes should
* be part of the actual string).
*
* If you cannot accurately determine the ETag, you should not return it.
* If you don't store the file exactly as-is (you're transforming it
* somehow) you should also not return an ETag.
*
* This means that if a subsequent GET to this new file does not exactly
* return the same contents of what was submitted here, you are strongly
* recommended to omit the ETag.
*
* @param string $name Name of the file
* @param resource $data Initial payload
* @return void
* @param resource|string $data Initial payload
* @return null|string
*/
public function createFile($name, $data = null) {

$newPath = $this->path . '/' . $name;
OC_Filesystem::file_put_contents($newPath,$data);

return OC_Connector_Sabre_Node::getETagPropertyForFile($newPath);
}

/**
Expand Down
25 changes: 21 additions & 4 deletions lib/connector/sabre/file.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
/**
* 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 void
* @return string|null
*/
public function put($data) {

OC_Filesystem::file_put_contents($this->path,$data);

return OC_Connector_Sabre_Node::getETagPropertyForFile($this->path);
}

/**
Expand Down Expand Up @@ -79,9 +94,11 @@ public function getSize() {
* @return mixed
*/
public function getETag() {

return null;

$properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME));
if (isset($properties[self::GETETAG_PROPERTYNAME])) {
return $properties[self::GETETAG_PROPERTYNAME];
}
return $this->getETagPropertyForFile($this->path);
}

/**
Expand Down
26 changes: 26 additions & 0 deletions lib/connector/sabre/node.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
const GETETAG_PROPERTYNAME = '{DAV:}getetag';

/**
* The path to the current node
Expand Down Expand Up @@ -200,4 +201,29 @@ function getProperties($properties) {
}
return $props;
}

/**
* Returns the ETag surrounded by double-quotes for this path.
* @param string $path Path of the file
* @return string|null Returns null if the ETag can not effectively be determined
*/
static public function getETagPropertyForFile($path) {
$tag = OC_Filesystem::hash('md5', $path);
if (empty($tag)) {
return null;
}
$etag = '"'.$tag.'"';
$query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' );
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag ));
return $etag;
}

/**
* Remove the ETag from the cache.
* @param string $path Path of the file
*/
static public function removeETagPropertyForFile($path) {
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' );
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME ));
}
}
8 changes: 8 additions & 0 deletions lib/filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,15 @@ static public function search($query){
static public function hasUpdated($path,$time){
return self::$defaultInstance->hasUpdated($path,$time);
}

static public function removeETagHook() {
$path=$params['path'];
OC_Connector_Sabre_Node::removeETagPropertyForFile($path);
}
}
OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook');
OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook');
OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook');

OC_Util::setupFS();
require_once('filecache.php');

0 comments on commit cdd9ffc

Please sign in to comment.