From a76498f24509700a34ae20fdf4ad67eb791a9298 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 2 Jun 2015 15:35:45 +0200 Subject: [PATCH 1/4] Add morrisjobke/webdav docker container for external storage tests --- .../tests/env/start-webdav-apache.sh | 74 +++++++++++++++++++ .../tests/env/stop-webdav-apache.sh | 36 +++++++++ 2 files changed, 110 insertions(+) create mode 100755 apps/files_external/tests/env/start-webdav-apache.sh create mode 100755 apps/files_external/tests/env/stop-webdav-apache.sh diff --git a/apps/files_external/tests/env/start-webdav-apache.sh b/apps/files_external/tests/env/start-webdav-apache.sh new file mode 100755 index 0000000000..8201424319 --- /dev/null +++ b/apps/files_external/tests/env/start-webdav-apache.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# +# ownCloud +# +# This script start a docker container to test the files_external tests +# against. It will also change the files_external config to use the docker +# container as testing environment. This is reverted in the stop step. +# +# If the environment variable RUN_DOCKER_MYSQL is set the ownCloud will +# be set up using MySQL instead of SQLite. +# +# Set environment variable DEBUG to print config file +# +# @author Morris Jobke +# @copyright 2014 Morris Jobke +# + +if ! command -v docker >/dev/null 2>&1; then + echo "No docker executable found - skipped docker setup" + exit 0; +fi + +echo "Docker executable found - setup docker" + +echo "Fetch recent morrisjobke/webdav docker image" +docker pull morrisjobke/webdav + +# retrieve current folder to place the config in the parent folder +thisFolder=`echo $0 | sed 's#env/start-webdav-apache\.sh##'` + +if [ -z "$thisFolder" ]; then + thisFolder="." +fi; + +container=`docker run -d -e USERNAME=test -e PASSWORD=test -p 8888:80 morrisjobke/webdav` + +# TODO find a way to determine the successful initialization inside the docker container +echo "Waiting 30 seconds for Webdav initialization ... " +sleep 30 + +# get mapped port on host for internal port 80 - output is IP:PORT - we need to extract the port with 'cut' +port=`docker port $container 80 | cut -f 2 -d :` + +cat > $thisFolder/config.webdav.php <true, + 'host'=>'localhost:$port/webdav/', + 'user'=>'test', + 'password'=>'test', + 'root'=>'', + // wait delay in seconds after write operations + // (only in tests) + // set to higher value for lighttpd webdav + 'wait'=> 0 +); + +DELIM + +echo "ownCloud container: $container" + +# put container IDs into a file to drop them after the test run (keep in mind that multiple tests run in parallel on the same host) +echo $container >> $thisFolder/dockerContainerWebdav.$EXECUTOR_NUMBER.webdav + +if [ -n "$databaseContainer" ]; then + echo "Database container: $databaseContainer" + echo $databaseContainer >> $thisFolder/dockerContainerWebdav.$EXECUTOR_NUMBER.webdav +fi + +if [ -n "$DEBUG" ]; then + cat $thisFolder/config.webdav.php + cat $thisFolder/dockerContainerWebdav.$EXECUTOR_NUMBER.webdav +fi diff --git a/apps/files_external/tests/env/stop-webdav-apache.sh b/apps/files_external/tests/env/stop-webdav-apache.sh new file mode 100755 index 0000000000..9ebf96030a --- /dev/null +++ b/apps/files_external/tests/env/stop-webdav-apache.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# ownCloud +# +# This script stops the docker container the files_external tests were run +# against. It will also revert the config changes done in start step. +# +# @author Morris Jobke +# @copyright 2014 Morris Jobke +# + +if ! command -v docker >/dev/null 2>&1; then + echo "No docker executable found - skipped docker stop" + exit 0; +fi + +echo "Docker executable found - stop and remove docker containers" + +# retrieve current folder to remove the config from the parent folder +thisFolder=`echo $0 | sed 's#env/stop-webdav-apache\.sh##'` + +if [ -z "$thisFolder" ]; then + thisFolder="." +fi; + +# stopping and removing docker containers +for container in `cat $thisFolder/dockerContainerWebdav.$EXECUTOR_NUMBER.webdav`; do + echo "Stopping and removing docker container $container" + # kills running container and removes it + docker rm -f $container +done; + +# cleanup +rm $thisFolder/config.webdav.php +rm $thisFolder/dockerContainerWebdav.$EXECUTOR_NUMBER.webdav + From 6f346b4b1f4512668e631ac57e71fac9061bc5fe Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 3 Jul 2015 19:49:25 +0200 Subject: [PATCH 2/4] Fix webdav destination header when overwriting folders The trailing slash is needed when talking to Apache's mod_dav server --- lib/private/Files/Storage/DAV.php | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php index 04910ece68..4713eb86fc 100644 --- a/lib/private/Files/Storage/DAV.php +++ b/lib/private/Files/Storage/DAV.php @@ -506,13 +506,18 @@ class DAV extends Common { $path1 = $this->cleanPath($path1); $path2 = $this->cleanPath($path2); try { + // overwrite directory ? + if ($this->is_dir($path2)) { + // needs trailing slash in destination + $path2 = rtrim($path2, '/') . '/'; + } $this->client->request( 'MOVE', $this->encodePath($path1), null, - array( - 'Destination' => $this->createBaseUri() . $this->encodePath($path2) - ) + [ + 'Destination' => $this->createBaseUri() . $this->encodePath($path2), + ] ); $this->statCache->clear($path1 . '/'); $this->statCache->clear($path2 . '/'); @@ -530,10 +535,22 @@ class DAV extends Common { /** {@inheritdoc} */ public function copy($path1, $path2) { $this->init(); - $path1 = $this->encodePath($this->cleanPath($path1)); - $path2 = $this->createBaseUri() . $this->encodePath($this->cleanPath($path2)); + $path1 = $this->cleanPath($path1); + $path2 = $this->cleanPath($path2); try { - $this->client->request('COPY', $path1, null, array('Destination' => $path2)); + // overwrite directory ? + if ($this->is_dir($path2)) { + // needs trailing slash in destination + $path2 = rtrim($path2, '/') . '/'; + } + $this->client->request( + 'COPY', + $this->encodePath($path1), + null, + [ + 'Destination' => $this->createBaseUri() . $this->encodePath($path2), + ] + ); $this->statCache->clear($path2 . '/'); $this->statCache->set($path2, true); $this->removeCachedFile($path2); From 5d7f37d57065715f09db2b61654044a027df4e91 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 1 Apr 2016 21:16:29 +0200 Subject: [PATCH 3/4] Check whether remote DAV server accepted the mtime on touch ownCloud as remote DAV always accepts the mtime on touch, but other servers like Apache's DAV server doesn't. The latter doesn't give any visible hint in its response to detect this case, so this fix does a subsequent PROPFIND to check whether the mtime was actually set. Since a touch() operation seldom happens (only on uploads), the minor performance loss should hopefully be acceptable. --- lib/private/Files/Storage/DAV.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php index 4713eb86fc..0d41b3bab0 100644 --- a/lib/private/Files/Storage/DAV.php +++ b/lib/private/Files/Storage/DAV.php @@ -449,7 +449,16 @@ class DAV extends Common { if ($this->file_exists($path)) { try { $this->statCache->remove($path); - $this->client->proppatch($this->encodePath($path), array('{DAV:}lastmodified' => $mtime)); + $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 (isset($response['{DAV:}getlastmodified'])) { + $remoteMtime = strtotime($response['{DAV:}getlastmodified']); + if ($remoteMtime !== $mtime) { + // server has not accepted the mtime + return false; + } + } } catch (ClientHttpException $e) { if ($e->getHttpStatus() === 501) { return false; From d201ffe13d74b326e0bf971674d2b162dc60baa0 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 3 May 2016 12:19:16 +0200 Subject: [PATCH 4/4] Fix webdav test env scripts to also work on CI --- .../tests/env/start-webdav-apache.sh | 30 ++++++++++++++----- .../tests/env/stop-webdav-apache.sh | 1 + 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/apps/files_external/tests/env/start-webdav-apache.sh b/apps/files_external/tests/env/start-webdav-apache.sh index 8201424319..48acb8572d 100755 --- a/apps/files_external/tests/env/start-webdav-apache.sh +++ b/apps/files_external/tests/env/start-webdav-apache.sh @@ -13,6 +13,7 @@ # # @author Morris Jobke # @copyright 2014 Morris Jobke +# @copyright 2016 Vincent Petry # if ! command -v docker >/dev/null 2>&1; then @@ -32,21 +33,36 @@ if [ -z "$thisFolder" ]; then thisFolder="." fi; -container=`docker run -d -e USERNAME=test -e PASSWORD=test -p 8888:80 morrisjobke/webdav` +if [ -n "$RUN_DOCKER_MYSQL" ]; then + echo "Fetch recent mysql docker image" + docker pull mysql -# TODO find a way to determine the successful initialization inside the docker container -echo "Waiting 30 seconds for Webdav initialization ... " -sleep 30 + echo "Setup MySQL ..." + # user/password will be read by ENV variables in owncloud container (they are generated by docker) + databaseContainer=`docker run -e MYSQL_ROOT_PASSWORD=mysupersecretpassword -d mysql` + containerName=`docker inspect $databaseContainer | grep Name | grep _ | cut -d \" -f 4 | cut -d / -f 2` -# get mapped port on host for internal port 80 - output is IP:PORT - we need to extract the port with 'cut' -port=`docker port $container 80 | cut -f 2 -d :` + parameter="--link $containerName:db" +fi + +container=`docker run -P $parameter -d -e USERNAME=test -e PASSWORD=test morrisjobke/webdav` +host=`docker inspect --format="{{.NetworkSettings.IPAddress}}" $container` + +echo -n "Waiting for Apache initialization on ${host}:${port}" +if ! "$thisFolder"/env/wait-for-connection ${host} 80 60; then + echo "[ERROR] Waited 60 seconds, no response" >&2 + exit 1 +fi + +# wait at least 5 more seconds - sometimes the webserver still needs some additional time +sleep 5 cat > $thisFolder/config.webdav.php <true, - 'host'=>'localhost:$port/webdav/', + 'host'=>'${host}:80/webdav/', 'user'=>'test', 'password'=>'test', 'root'=>'', diff --git a/apps/files_external/tests/env/stop-webdav-apache.sh b/apps/files_external/tests/env/stop-webdav-apache.sh index 9ebf96030a..e898a65cc3 100755 --- a/apps/files_external/tests/env/stop-webdav-apache.sh +++ b/apps/files_external/tests/env/stop-webdav-apache.sh @@ -7,6 +7,7 @@ # # @author Morris Jobke # @copyright 2014 Morris Jobke +# @copyright 2016 Vincent Petry # if ! command -v docker >/dev/null 2>&1; then