Merge pull request #2744 from nextcloud/oc_26324
[downstream] Fix DAV stat cache to properly cache 404
This commit is contained in:
commit
447e388ce9
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue