Merge pull request #2744 from nextcloud/oc_26324

[downstream] Fix DAV stat cache to properly cache 404
This commit is contained in:
Roeland Jago Douma 2017-01-11 08:16:40 +01:00 committed by GitHub
commit 447e388ce9
1 changed files with 53 additions and 52 deletions

View File

@ -49,7 +49,6 @@ use OCP\Files\StorageInvalidException;
use OCP\Files\StorageNotAvailableException;
use OCP\Util;
use Sabre\DAV\Client;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Xml\Property\ResourceType;
use Sabre\HTTP\ClientException;
use Sabre\HTTP\ClientHttpException;
@ -202,13 +201,15 @@ class DAV extends Common {
$this->init();
$path = $this->cleanPath($path);
try {
$response = $this->client->propfind(
$response = $this->client->propFind(
$this->encodePath($path),
array(),
[],
1
);
$id = md5('webdav' . $this->root . $path);
$content = array();
if ($response === false) {
return false;
}
$content = [];
$files = array_keys($response);
array_shift($files); //the first entry is the current directory
@ -225,13 +226,6 @@ class DAV extends Common {
$content[] = $file;
}
return IteratorDirectory::wrap($content);
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
$this->statCache->clear($path . '/');
$this->statCache->set($path, false);
return false;
}
$this->convertException($e, $path);
} catch (\Exception $e) {
$this->convertException($e, $path);
}
@ -246,22 +240,18 @@ class DAV extends Common {
*
* @param string $path path to propfind
*
* @return array propfind response
* @return array|boolean propfind response or false if the entry was not found
*
* @throws NotFound
* @throws ClientHttpException
*/
protected function propfind($path) {
$path = $this->cleanPath($path);
$cachedResponse = $this->statCache->get($path);
if ($cachedResponse === false) {
// we know it didn't exist
throw new NotFound();
}
// we either don't know it, or we know it exists but need more details
if (is_null($cachedResponse) || $cachedResponse === true) {
$this->init();
try {
$response = $this->client->propfind(
$response = $this->client->propFind(
$this->encodePath($path),
array(
'{DAV:}getlastmodified',
@ -274,11 +264,15 @@ class DAV extends Common {
)
);
$this->statCache->set($path, $response);
} catch (NotFound $e) {
// remember that this path did not exist
$this->statCache->clear($path . '/');
$this->statCache->set($path, false);
throw $e;
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
$this->statCache->clear($path . '/');
$this->statCache->set($path, false);
return false;
}
$this->convertException($e, $path);
} catch (\Exception $e) {
$this->convertException($e, $path);
}
} else {
$response = $cachedResponse;
@ -290,17 +284,15 @@ class DAV extends Common {
public function filetype($path) {
try {
$response = $this->propfind($path);
$responseType = array();
if ($response === false) {
return false;
}
$responseType = [];
if (isset($response["{DAV:}resourcetype"])) {
/** @var ResourceType[] $response */
$responseType = $response["{DAV:}resourcetype"]->getValue();
}
return (count($responseType) > 0 and $responseType[0] == "{DAV:}collection") ? 'dir' : 'file';
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
return false;
}
$this->convertException($e, $path);
} catch (\Exception $e) {
$this->convertException($e, $path);
}
@ -319,13 +311,7 @@ class DAV extends Common {
return true;
}
// need to get from server
$this->propfind($path);
return true; //no 404 exception
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
return false;
}
$this->convertException($e, $path);
return ($this->propfind($path) !== false);
} catch (\Exception $e) {
$this->convertException($e, $path);
}
@ -429,7 +415,10 @@ class DAV extends Common {
$path = $this->cleanPath($path);
try {
// TODO: cacheable ?
$response = $this->client->propfind($this->encodePath($path), array('{DAV:}quota-available-bytes'));
$response = $this->client->propfind($this->encodePath($path), ['{DAV:}quota-available-bytes']);
if ($response === false) {
return FileInfo::SPACE_UNKNOWN;
}
if (isset($response['{DAV:}quota-available-bytes'])) {
return (int)$response['{DAV:}quota-available-bytes'];
} else {
@ -455,6 +444,9 @@ class DAV extends Common {
$this->client->proppatch($this->encodePath($path), ['{DAV:}lastmodified' => $mtime]);
// non-owncloud clients might not have accepted the property, need to recheck it
$response = $this->client->propfind($this->encodePath($path), ['{DAV:}getlastmodified'], 0);
if ($response === false) {
return false;
}
if (isset($response['{DAV:}getlastmodified'])) {
$remoteMtime = strtotime($response['{DAV:}getlastmodified']);
if ($remoteMtime !== $mtime) {
@ -577,15 +569,13 @@ class DAV extends Common {
public function stat($path) {
try {
$response = $this->propfind($path);
return array(
if ($response === false) {
return [];
}
return [
'mtime' => strtotime($response['{DAV:}getlastmodified']),
'size' => (int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0,
);
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
return array();
}
$this->convertException($e, $path);
];
} catch (\Exception $e) {
$this->convertException($e, $path);
}
@ -596,7 +586,10 @@ class DAV extends Common {
public function getMimeType($path) {
try {
$response = $this->propfind($path);
$responseType = array();
if ($response === false) {
return false;
}
$responseType = [];
if (isset($response["{DAV:}resourcetype"])) {
/** @var ResourceType[] $response */
$responseType = $response["{DAV:}resourcetype"]->getValue();
@ -609,11 +602,6 @@ class DAV extends Common {
} else {
return false;
}
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
return false;
}
$this->convertException($e, $path);
} catch (\Exception $e) {
$this->convertException($e, $path);
}
@ -704,6 +692,9 @@ class DAV extends Common {
$this->init();
$path = $this->cleanPath($path);
$response = $this->propfind($path);
if ($response === false) {
return 0;
}
if (isset($response['{http://owncloud.org/ns}permissions'])) {
return $this->parsePermissions($response['{http://owncloud.org/ns}permissions']);
} else if ($this->is_dir($path)) {
@ -720,6 +711,9 @@ class DAV extends Common {
$this->init();
$path = $this->cleanPath($path);
$response = $this->propfind($path);
if ($response === false) {
return null;
}
if (isset($response['{DAV:}getetag'])) {
return trim($response['{DAV:}getetag'], '"');
}
@ -763,6 +757,13 @@ class DAV extends Common {
// force refresh for $path
$this->statCache->remove($path);
$response = $this->propfind($path);
if ($response === false) {
if ($path === '') {
// if root is gone it means the storage is not available
throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
}
return false;
}
if (isset($response['{DAV:}getetag'])) {
$cachedData = $this->getCache()->get($path);
$etag = null;
@ -785,7 +786,7 @@ class DAV extends Common {
return $remoteMtime > $time;
}
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404 || $e->getHttpStatus() === 405) {
if ($e->getHttpStatus() === 405) {
if ($path === '') {
// if root is gone it means the storage is not available
throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());