diff --git a/lib/autoloader.php b/lib/autoloader.php index 9615838a9a..2117063909 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -96,8 +96,8 @@ class Autoloader { } else { foreach ($this->prefixPaths as $prefix => $dir) { if (0 === strpos($class, $prefix)) { - $path = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'; - $path = str_replace('_', DIRECTORY_SEPARATOR, $path); + $path = str_replace('\\', '/', $class) . '.php'; + $path = str_replace('_', '/', $path); $paths[] = $dir . '/' . $path; } } diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 417a47f383..87c33a313a 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Cache; +use OCP\Util; /** * listen to filesystem hooks and change the cache accordingly @@ -102,7 +103,7 @@ class Updater { static public function correctFolder($path, $time) { if ($path !== '' && $path !== '/') { $parent = dirname($path); - if ($parent === '.') { + if ($parent === '.' || $parent === '\\') { $parent = ''; } /** @@ -116,6 +117,8 @@ class Updater { if ($id !== -1) { $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); self::correctFolder($parent, $time); + } else { + Util::writeLog('core', 'Path not in cache: '.$internalPath, Util::ERROR); } } } diff --git a/lib/files/view.php b/lib/files/view.php index e2fc8d965b..25071709fb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -386,6 +386,12 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); + + // close open handle - especially $source is necessary because unlink below will + // throw an exception on windows because the file is locked + fclose($source); + fclose($target); + if ($result !== false) { list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index dad3cd7e65..874a35e2c6 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -56,7 +56,7 @@ class Updater extends \PHPUnit_Framework_TestCase { \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); - + \OC_Hook::connect('OC_Filesystem', 'post_touch', '\OC\Files\Cache\Updater', 'touchHook'); } public function tearDown() { @@ -96,6 +96,27 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime); } + public function testWriteWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $cachedData = $cache2->get('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + $mtime = $cachedData['mtime']; + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + } + public function testDelete() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -103,7 +124,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); - Filesystem::unlink('foo.txt', 'asd'); + Filesystem::unlink('foo.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); @@ -123,6 +144,26 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } + public function testDeleteWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + Filesystem::unlink('folder/substorage/foo.txt'); + $this->assertFalse($cache2->inCache('foo.txt')); + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($substorageCachedData['mtime'], $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($folderCachedData['mtime'], $cachedData['mtime']); + } + public function testRename() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -142,4 +183,85 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } -} + + public function testRenameWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + $fooCachedData = $cache2->get('foo.txt'); + Filesystem::rename('folder/substorage/foo.txt', 'folder/substorage/bar.txt'); + $this->assertFalse($cache2->inCache('foo.txt')); + $this->assertTrue($cache2->inCache('bar.txt')); + $cachedData = $cache2->get('bar.txt'); + $this->assertEquals($fooCachedData['fileid'], $cachedData['fileid']); + $mtime = $cachedData['mtime']; + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); + } + + public function testTouch() { + $rootCachedData = $this->cache->get(''); + $fooCachedData = $this->cache->get('foo.txt'); + Filesystem::touch('foo.txt'); + $cachedData = $this->cache->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']); + + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); + $rootCachedData = $cachedData; + + $time = 1371006070; + $barCachedData = $this->cache->get('folder/bar.txt'); + $folderCachedData = $this->cache->get('folder'); + Filesystem::touch('folder/bar.txt', $time); + $cachedData = $this->cache->get('folder/bar.txt'); + $this->assertNotEquals($barCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + } + + public function testTouchWithMountPoints() { + $storage2 = new \OC\Files\Storage\Temporary(array()); + $cache2 = $storage2->getCache(); + Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); + Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); + $this->assertTrue($cache2->inCache('foo.txt')); + $folderCachedData = $this->cache->get('folder'); + $substorageCachedData = $cache2->get(''); + $fooCachedData = $cache2->get('foo.txt'); + $cachedData = $cache2->get('foo.txt'); + $time = 1371006070; + Filesystem::touch('folder/substorage/foo.txt', $time); + $cachedData = $cache2->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $cache2->get(''); + $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + + $cachedData = $this->cache->get('folder'); + $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertEquals($time, $cachedData['mtime']); + } + +} \ No newline at end of file