diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index cb92787..6e3fdd6 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -320,6 +320,8 @@ def __init__(self, url, **kwargs): :param url: URL of the target ownCloud instance :param verify_certs: True (default) to verify SSL certificates, False otherwise + :param dav_endpoint_version: None (default) to force using a specific endpoint version + instead of relying on capabilities :param debug: set to True to print debugging messages to stdout, defaults to False """ if not url.endswith('/'): @@ -329,14 +331,11 @@ def __init__(self, url, **kwargs): self._session = None self._debug = kwargs.get('debug', False) self._verify_certs = kwargs.get('verify_certs', True) + self._dav_endpoint_version = kwargs.get('dav_endpoint_version', True) self._capabilities = None self._version = None - url_components = parse.urlparse(url) - self._davpath = url_components.path + 'remote.php/webdav' - self._webdav_url = url + 'remote.php/webdav' - def login(self, user_id, password): """Authenticate to ownCloud. This will create a session on the server. @@ -352,6 +351,15 @@ def login(self, user_id, password): try: self._update_capabilities() + + url_components = parse.urlparse(self.url) + if self._dav_endpoint_version == 1: + self._davpath = url_components.path + 'remote.php/dav/files/' + parse.quote(user_id) + self._webdav_url = self.url + 'remote.php/dav/files/' + parse.quote(user_id) + else: + self._davpath = url_components.path + 'remote.php/webdav' + self._webdav_url = self.url + 'remote.php/webdav' + except HTTPResponseError as e: self._session.close() self._session = None @@ -1814,5 +1822,15 @@ def _update_capabilities(self): if edition_el.text is not None: self._version += '-' + edition_el.text + if 'dav' in apps and 'chunking' in apps['dav']: + chunking_version = float(apps['dav']['chunking']) + if self._dav_endpoint_version > chunking_version: + self._dav_endpoint_version = None + + if self._dav_endpoint_version is None and chunking_version >= 1.0: + self._dav_endpoint_version = 1 + else: + self._dav_endpoint_version = 0 + return self._capabilities raise HTTPResponseError(res) diff --git a/owncloud/test/test.py b/owncloud/test/test.py index bce0e5c..e8d28db 100644 --- a/owncloud/test/test.py +++ b/owncloud/test/test.py @@ -9,13 +9,35 @@ import datetime import time import tempfile +import random import six from config import Config +def getSupportedDavVersion(): + # connect just to check supported DAV version + client = owncloud.Client(Config['owncloud_url']) + client.login(Config['owncloud_login'], Config['owncloud_password']) + + caps = client.get_capabilities() + dav_version = None + + if 'dav' in caps and 'chunking' in caps['dav']: + dav_version = float(caps['dav']['chunking']) + + return dav_version + +def skipIfDavVersionLessThan(expected_version): + dav_version = getSupportedDavVersion() + if dav_version is None or dav_version < expected_version: + return unittest.skip("Expected DAV version %s not supported in this ownCloud version" % expected_version) + return lambda func: func class TestFileAccess(unittest.TestCase): + def get_dav_endpoint_version(self): + return 0 + def files(): return ( ['test.txt'], @@ -31,10 +53,10 @@ def files_content(): ) def setUp(self): - self.temp_dir = tempfile.gettempdir() + '/pyocclient_test%s/' % int(time.time()) + self.temp_dir = tempfile.gettempdir() + '/pyocclient_test%s-%s/' % (int(time.time()), random.randint(1, 1000)) os.mkdir(self.temp_dir) - self.client = owncloud.Client(Config['owncloud_url']) + self.client = owncloud.Client(Config['owncloud_url'], dav_endpoint_version=self.get_dav_endpoint_version()) self.client.login(Config['owncloud_login'], Config['owncloud_password']) self.test_root = Config['test_root'] if not self.test_root[-1] == '/': @@ -862,6 +884,10 @@ def test_update_share_password(self): self.assertTrue(type(share_info.get_share_with_displayname()) is str) self.assertTrue(self.client.delete_share(share_id)) +@skipIfDavVersionLessThan(1.0) +class TestFileAccessDav1(TestFileAccess): + def get_dav_endpoint_version(self): + return 1 class TestPrivateDataAccess(unittest.TestCase):