4141use Icewind \Streams \CallbackWrapper ;
4242use Icewind \Streams \IteratorDirectory ;
4343use OC \Files \Filesystem ;
44- use OC \MemCache \ArrayCache ;
44+ use OC \Memcache \ArrayCache ;
4545use OCP \AppFramework \Http ;
4646use OCP \Constants ;
4747use OCP \Diagnostics \IEventLogger ;
@@ -86,6 +86,8 @@ class DAV extends Common {
8686 protected $ client ;
8787 /** @var ArrayCache */
8888 protected $ statCache ;
89+ /** @var ArrayCache */
90+ protected $ propfindCache ;
8991 /** @var IClientService */
9092 protected $ httpClientService ;
9193 /** @var ICertificateManager */
@@ -99,6 +101,7 @@ class DAV extends Common {
99101 */
100102 public function __construct ($ params ) {
101103 $ this ->statCache = new ArrayCache ();
104+ $ this ->propfindCache = new ArrayCache ();
102105 $ this ->httpClientService = \OC ::$ server ->getHTTPClientService ();
103106 if (isset ($ params ['host ' ]) && isset ($ params ['user ' ]) && isset ($ params ['password ' ])) {
104107 $ host = $ params ['host ' ];
@@ -225,6 +228,7 @@ public function rmdir($path) {
225228 $ result = $ this ->simpleResponse ('DELETE ' , $ path . '/ ' , null , 204 );
226229 $ this ->statCache ->clear ($ path . '/ ' );
227230 $ this ->statCache ->remove ($ path );
231+ $ this ->propfindCache ->remove ($ path );
228232 return $ result ;
229233 }
230234
@@ -235,7 +239,16 @@ public function opendir($path) {
235239 try {
236240 $ response = $ this ->client ->propFind (
237241 $ this ->encodePath ($ path ),
238- ['{DAV:}getetag ' ],
242+ [
243+ '{DAV:}getlastmodified ' ,
244+ '{DAV:}getcontentlength ' ,
245+ '{DAV:}getcontenttype ' ,
246+ '{http://owncloud.org/ns}permissions ' ,
247+ '{http://open-collaboration-services.org/ns}share-permissions ' ,
248+ '{DAV:}resourcetype ' ,
249+ '{DAV:}getetag ' ,
250+ '{DAV:}quota-available-bytes ' ,
251+ ],
239252 1
240253 );
241254 if ($ response === false ) {
@@ -254,7 +267,9 @@ public function opendir($path) {
254267 if (!$ this ->statCache ->hasKey ($ path )) {
255268 $ this ->statCache ->set ($ file , true );
256269 }
270+ $ fileDetail = $ response [$ file ];
257271 $ file = basename ($ file );
272+ $ this ->propfindCache ->set ($ file , $ fileDetail );
258273 $ content [] = $ file ;
259274 }
260275 return IteratorDirectory::wrap ($ content );
@@ -278,6 +293,10 @@ public function opendir($path) {
278293 */
279294 protected function propfind ($ path ) {
280295 $ path = $ this ->cleanPath ($ path );
296+ $ propfindCacheResponse = $ this ->propfindCache ->get ($ path );
297+ if (!is_null ($ propfindCacheResponse )) {
298+ return $ propfindCacheResponse ;
299+ }
281300 $ cachedResponse = $ this ->statCache ->get ($ path );
282301 // we either don't know it, or we know it exists but need more details
283302 if (is_null ($ cachedResponse ) || $ cachedResponse === true ) {
@@ -297,6 +316,7 @@ protected function propfind($path) {
297316 ]
298317 );
299318 $ this ->statCache ->set ($ path , $ response );
319+ $ this ->propfindCache ->set ($ path , $ response );
300320 } catch (ClientHttpException $ e ) {
301321 if ($ e ->getHttpStatus () === 404 || $ e ->getHttpStatus () === 405 ) {
302322 $ this ->statCache ->clear ($ path . '/ ' );
@@ -358,6 +378,7 @@ public function unlink($path) {
358378 $ result = $ this ->simpleResponse ('DELETE ' , $ path , null , 204 );
359379 $ this ->statCache ->clear ($ path . '/ ' );
360380 $ this ->statCache ->remove ($ path );
381+ $ this ->propfindCache ->remove ($ path );
361382 return $ result ;
362383 }
363384
@@ -473,6 +494,7 @@ public function touch($path, $mtime = null) {
473494 if ($ this ->file_exists ($ path )) {
474495 try {
475496 $ this ->statCache ->remove ($ path );
497+ $ this ->propfindCache ->remove ($ path );
476498 $ this ->client ->proppatch ($ this ->encodePath ($ path ), ['{DAV:}lastmodified ' => $ mtime ]);
477499 // non-owncloud clients might not have accepted the property, need to recheck it
478500 $ response = $ this ->client ->propfind ($ this ->encodePath ($ path ), ['{DAV:}getlastmodified ' ], 0 );
@@ -511,6 +533,7 @@ public function file_put_contents($path, $data) {
511533 $ path = $ this ->cleanPath ($ path );
512534 $ result = parent ::file_put_contents ($ path , $ data );
513535 $ this ->statCache ->remove ($ path );
536+ $ this ->propfindCache ->remove ($ path );
514537 return $ result ;
515538 }
516539
@@ -524,6 +547,7 @@ protected function uploadFile($path, $target) {
524547 // invalidate
525548 $ target = $ this ->cleanPath ($ target );
526549 $ this ->statCache ->remove ($ target );
550+ $ this ->propfindCache ->remove ($ target );
527551 $ source = fopen ($ path , 'r ' );
528552
529553 $ this ->httpClientService
@@ -800,6 +824,7 @@ public function hasUpdated($path, $time) {
800824 try {
801825 // force refresh for $path
802826 $ this ->statCache ->remove ($ path );
827+ $ this ->propfindCache ->remove ($ path );
803828 $ response = $ this ->propfind ($ path );
804829 if ($ response === false ) {
805830 if ($ path === '' ) {
0 commit comments