Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A couple of baseurl-related fixes. #19

Merged
merged 4 commits into from
Dec 30, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
* davcmd.py:
  * reimplemented `copytree()` URI derivation logic using `urllib.parse`
    and `os.path`.
* WebDAVServer.py, propfind.py, davcopy.py, utils:
  * Moved the responsibility of adding newlines to the end of response
    XML out of WebDAVServer.py and into the XML generation routines in
    propfind.py, davcopy.py, and utils.py.
* utils.py:
  * Altered `is_prefix()` to use `os.path.commonpath()` instead of
    a substring comparison.
  • Loading branch information
jaysonlarose authored and pi-anl committed Dec 30, 2022
commit 86f8c86a73ee0cc4d0d62da79ebc1cdebbb9c3a4
48 changes: 35 additions & 13 deletions pywebdav/lib/davcmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .utils import create_treelist, is_prefix
from .errors import *
from six.moves import range
import os

def deltree(dc,uri,exclude={}):
""" delete a tree of resources
Expand Down Expand Up @@ -128,7 +129,7 @@ def copytree(dc,src,dst,overwrite=None):
dc -- dataclass to use
src -- src uri from where to copy
dst -- dst uri
overwrite -- if 1 then delete dst uri before
overwrite -- if True then delete dst uri before

returns dict of uri:error_code tuples from which
another method can create a multistatus xml element.
Expand All @@ -149,8 +150,14 @@ def copytree(dc,src,dst,overwrite=None):
tlist = create_treelist(dc,src)
result = {}

# prepare destination URIs (get the prefix)
dpath = urllib.parse.urlparse(dst)[2]
# Extract the path out of the source URI.
src_path = urllib.parse.urlparse(src).path

# Parse the destination URI.
# We'll be using it to construct destination URIs,
# so we don't just retain the path, like we did with
# the source.
dst_parsed = urllib.parse.urlparse(dst)

for element in tlist:
problem_uris = list(result.keys())
Expand All @@ -160,24 +167,34 @@ def copytree(dc,src,dst,overwrite=None):
# able to copy in problem_uris which is the prefix
# of the actual element. If it is, then we cannot
# copy this as well but do not generate another error.
ok=1
ok=True
for p in problem_uris:
if is_prefix(p,element):
ok=None
ok=False
break

if not ok: continue
if not ok:
continue

# Find the element's path relative to the source.
element_path = urllib.parse.urlparse(element).path
element_path_rel = os.path.relpath(element_path, start=src_path)
# Append this relative path to the destination.
if element_path_rel == '.':
# os.path.relpath("/somedir", start="/somedir") returns
# a result of ".", which we don't want to append to the
# destination path.
dst_path = dst_parsed.path
else:
dst_path = os.path.join(dst_parsed.path, element_path_rel)

# Generate destination URI using our derived destination path.
dst_uri = urllib.parse.urlunparse(dst_parsed._replace(path=os.path.join(dst_parsed.path, element_path_rel)))

# now create the destination URI which corresponds to
# the actual source URI. -> actual_dst
# ("subtract" the base src from the URI and prepend the
# dst prefix to it.)
esrc=element.replace(src,b"")
actual_dst=dpath+esrc

# now copy stuff
try:
copy(dc,element,actual_dst)
copy(dc,element,dst_uri)
except DAV_Error as error:
(ec,dd) = error.args
result[element]=ec
Expand Down Expand Up @@ -216,6 +233,11 @@ def movetree(dc,src,dst,overwrite=None):
# first copy it
res = copytree(dc,src,dst,overwrite)

# TODO: shouldn't we check res for errors and bail out before
# the delete if we find any?
# TODO: or, better yet, is there anything preventing us from
# reimplementing this using `shutil.move()`?

# then delete it
res = deltree(dc,src,exclude=res)

Expand Down
2 changes: 1 addition & 1 deletion pywebdav/lib/davcopy.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ def tree_action(self):
re.appendChild(st)
ms.appendChild(re)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"
4 changes: 2 additions & 2 deletions pywebdav/lib/propfind.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def create_propname(self):
if uri_childs:
uri_list.extend(uri_childs)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"

def create_allprop(self):
""" return a list of all properties """
Expand Down Expand Up @@ -180,7 +180,7 @@ def create_prop(self):
if uri_childs:
uri_list.extend(uri_childs)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"

def mk_propname_response(self, uri, propnames, doc):
""" make a new <prop> result element for a PROPNAME request
Expand Down
4 changes: 2 additions & 2 deletions pywebdav/lib/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def create_propname(self):
if uri_childs:
uri_list.extend(uri_childs)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"

def create_prop(self):
""" handle a <prop> request
Expand Down Expand Up @@ -117,5 +117,5 @@ def create_prop(self):
if uri_childs:
uri_list.extend(uri_childs)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"

10 changes: 5 additions & 5 deletions pywebdav/lib/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import time
import re
import os

from xml.dom import minidom
from six.moves import urllib
Expand Down Expand Up @@ -75,10 +76,9 @@ def create_treelist(dataclass,uri):

def is_prefix(uri1,uri2):
""" returns 1 of uri1 is a prefix of uri2 """
if uri2[:len(uri1)]==uri1:
return 1
else:
return None
path1 = urllib.parse.urlparse(uri1).path
path2 = urllib.parse.urlparse(uri2).path
return os.path.commonpath([path1, path2]) == path2
jaysonlarose marked this conversation as resolved.
Show resolved Hide resolved

def quote_uri(uri):
""" quote an URL but not the protocol part """
Expand Down Expand Up @@ -122,7 +122,7 @@ def make_xmlresponse(result):
re.appendChild(st)
doc.documentElement.appendChild(re)

return doc.toxml(encoding="utf-8")
return doc.toxml(encoding="utf-8") + b"\n"

# taken from App.Common

Expand Down