* Add extra db column to filecache * Bump version * Update filecache code to actually handle checksum * Webdav code to store/retrieve checksumstags/v9.0beta1
@@ -214,7 +214,13 @@ class File extends Node implements IFile { | |||
header('X-OC-MTime: accepted'); | |||
} | |||
} | |||
if (isset($request->server['HTTP_OC_CHECKSUM'])) { | |||
$checksum = trim($request->server['HTTP_OC_CHECKSUM']); | |||
$this->fileView->putFileInfo($this->path, ['checksum' => $checksum]); | |||
} | |||
$this->refreshInfo(); | |||
} catch (StorageNotAvailableException $e) { | |||
throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage()); | |||
} | |||
@@ -528,4 +534,13 @@ class File extends Node implements IFile { | |||
throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e); | |||
} | |||
/** | |||
* Get the checksum for this file | |||
* | |||
* @return string | |||
*/ | |||
public function getChecksum() { | |||
return $this->info->getChecksum(); | |||
} | |||
} |
@@ -47,6 +47,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { | |||
const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified'; | |||
const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id'; | |||
const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name'; | |||
const CHECKSUM_PROPERTYNAME = '{http://owncloud.org/ns}checksum'; | |||
/** | |||
* Reference to main server object | |||
@@ -107,6 +108,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { | |||
$server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME; | |||
$server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME; | |||
$server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME; | |||
$server->protectedProperties[] = self::CHECKSUM_PROPERTYNAME; | |||
// normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH | |||
$allowedProperties = ['{DAV:}getetag']; | |||
@@ -178,8 +180,8 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { | |||
} | |||
/** | |||
* Plugin that adds a 'Content-Disposition: attachment' header to all files | |||
* delivered by SabreDAV. | |||
* Add headers to file download | |||
* | |||
* @param RequestInterface $request | |||
* @param ResponseInterface $response | |||
*/ | |||
@@ -188,7 +190,15 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { | |||
$node = $this->tree->getNodeForPath($request->getPath()); | |||
if (!($node instanceof IFile)) return; | |||
// adds a 'Content-Disposition: attachment' header | |||
$response->addHeader('Content-Disposition', 'attachment'); | |||
//Add OC-Checksum header | |||
/** @var $node File */ | |||
$checksum = $node->getChecksum(); | |||
if ($checksum !== null) { | |||
$response->addHeader('OC-Checksum', $checksum); | |||
} | |||
} | |||
/** | |||
@@ -237,6 +247,16 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { | |||
} | |||
return false; | |||
}); | |||
$propFind->handle(self::CHECKSUM_PROPERTYNAME, function() use ($node) { | |||
$checksum = $node->getChecksum(); | |||
if ($checksum === null) { | |||
return ''; | |||
} | |||
return $checksum; | |||
}); | |||
} | |||
if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) { |
@@ -397,6 +397,14 @@ | |||
<length>4</length> | |||
</field> | |||
<field> | |||
<name>checksum</name> | |||
<type>text</type> | |||
<default></default> | |||
<notnull>false</notnull> | |||
<length>255</length> | |||
</field> | |||
<index> | |||
<name>fs_storage_path_hash</name> |
@@ -121,7 +121,7 @@ class Cache implements ICache { | |||
$params = array($file); | |||
} | |||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, | |||
`storage_mtime`, `encrypted`, `etag`, `permissions` | |||
`storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum` | |||
FROM `*PREFIX*filecache` ' . $where; | |||
$result = $this->connection->executeQuery($sql, $params); | |||
$data = $result->fetch(); | |||
@@ -177,7 +177,7 @@ class Cache implements ICache { | |||
public function getFolderContentsById($fileId) { | |||
if ($fileId > -1) { | |||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, | |||
`storage_mtime`, `encrypted`, `etag`, `permissions` | |||
`storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum` | |||
FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'; | |||
$result = $this->connection->executeQuery($sql, [$fileId]); | |||
$files = $result->fetchAll(); | |||
@@ -287,7 +287,10 @@ class Cache implements ICache { | |||
// don't update if the data we try to set is the same as the one in the record | |||
// some databases (Postgres) don't like superfluous updates | |||
$sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' . | |||
'WHERE (' . implode(' <> ? OR ', $queryParts) . ' <> ? ) AND `fileid` = ? '; | |||
'WHERE (' . | |||
implode(' <> ? OR ', $queryParts) . ' <> ? OR ' . | |||
implode(' IS NULL OR ', $queryParts) . ' IS NULL' . | |||
') AND `fileid` = ? '; | |||
$this->connection->executeQuery($sql, $params); | |||
} | |||
@@ -303,7 +306,7 @@ class Cache implements ICache { | |||
protected function buildParts(array $data) { | |||
$fields = array( | |||
'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', | |||
'etag', 'permissions'); | |||
'etag', 'permissions', 'checksum'); | |||
$doNotCopyStorageMTime = false; | |||
if (array_key_exists('mtime', $data) && $data['mtime'] === null) { | |||
@@ -567,7 +570,7 @@ class Cache implements ICache { | |||
$sql = ' | |||
SELECT `fileid`, `storage`, `path`, `parent`, `name`, | |||
`mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, | |||
`etag`, `permissions` | |||
`etag`, `permissions`, `checksum` | |||
FROM `*PREFIX*filecache` | |||
WHERE `storage` = ? AND `name` ILIKE ?'; | |||
$result = $this->connection->executeQuery($sql, | |||
@@ -598,7 +601,7 @@ class Cache implements ICache { | |||
} else { | |||
$where = '`mimepart` = ?'; | |||
} | |||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`, `permissions` | |||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum` | |||
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; | |||
$mimetype = $this->mimetypeLoader->getId($mimetype); | |||
$result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId())); | |||
@@ -625,7 +628,7 @@ class Cache implements ICache { | |||
public function searchByTag($tag, $userId) { | |||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, ' . | |||
'`mimetype`, `mimepart`, `size`, `mtime`, ' . | |||
'`encrypted`, `etag`, `permissions` ' . | |||
'`encrypted`, `etag`, `permissions`, `checksum` ' . | |||
'FROM `*PREFIX*filecache` `file`, ' . | |||
'`*PREFIX*vcategory_to_object` `tagmap`, ' . | |||
'`*PREFIX*vcategory` `tag` ' . |
@@ -327,4 +327,11 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { | |||
$this->childEtags[] = $relativeEntryPath . '/' . $data['etag'] . $permissions; | |||
} | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function getChecksum() { | |||
return $this->data['checksum']; | |||
} | |||
} |
@@ -164,4 +164,11 @@ class File extends Node implements \OCP\Files\File { | |||
public function hash($type, $raw = false) { | |||
return $this->view->hash($type, $this->path, $raw); | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function getChecksum() { | |||
return $this->fileInfo->getChecksum(); | |||
} | |||
} |
@@ -351,4 +351,8 @@ class Node implements \OCP\Files\Node { | |||
public function getOwner() { | |||
return $this->getFileInfo()->getOwner(); | |||
} | |||
public function getChecksum() { | |||
return; | |||
} | |||
} |
@@ -237,4 +237,12 @@ interface FileInfo { | |||
* @since 9.0.0 | |||
*/ | |||
public function getOwner(); | |||
/** | |||
* Get the stored checksum for this file | |||
* | |||
* @return string | |||
* @since 9.0.0 | |||
*/ | |||
public function getChecksum(); | |||
} |
@@ -25,7 +25,7 @@ | |||
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades | |||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | |||
// when updating major/minor version number. | |||
$OC_Version = array(9, 0, 0, 8); | |||
$OC_Version = array(9, 0, 0, 9); | |||
// The human readable string | |||
$OC_VersionString = '9.0 pre alpha'; |