mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-21 02:01:31 +00:00
webish: implement replace= for PUT commands
This commit is contained in:
parent
42dcc3088e
commit
1752c9e29e
@ -400,6 +400,8 @@ class Web(WebMixin, unittest.TestCase):
|
||||
def test_PUT_NEWFILEURL(self):
|
||||
d = self.PUT("/vdrive/global/foo/new.txt", self.NEWFILE_CONTENTS)
|
||||
def _check(res):
|
||||
# TODO: we lose the response code, so we can't check this
|
||||
#self.failUnlessEqual(responsecode, 201)
|
||||
self.failUnless("new.txt" in self._foo_node.children)
|
||||
new_uri = self._foo_node.children["new.txt"]
|
||||
new_contents = self.files[new_uri]
|
||||
@ -408,6 +410,28 @@ class Web(WebMixin, unittest.TestCase):
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWFILEURL_replace(self):
|
||||
d = self.PUT("/vdrive/global/foo/bar.txt", self.NEWFILE_CONTENTS)
|
||||
def _check(res):
|
||||
# TODO: we lose the response code, so we can't check this
|
||||
#self.failUnlessEqual(responsecode, 200)
|
||||
self.failUnless("bar.txt" in self._foo_node.children)
|
||||
new_uri = self._foo_node.children["bar.txt"]
|
||||
new_contents = self.files[new_uri]
|
||||
self.failUnlessEqual(new_contents, self.NEWFILE_CONTENTS)
|
||||
self.failUnlessEqual(res.strip(), new_uri)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWFILEURL_no_replace(self):
|
||||
d = self.PUT("/vdrive/global/foo/bar.txt?replace=false",
|
||||
self.NEWFILE_CONTENTS)
|
||||
d.addBoth(self.shouldFail, error.Error, "PUT_NEWFILEURL_no_replace",
|
||||
"409 Conflict",
|
||||
"There was already a child by that name, and you asked me "
|
||||
"to not replace it")
|
||||
return d
|
||||
|
||||
def test_PUT_NEWFILEURL_mkdirs(self):
|
||||
d = self.PUT("/vdrive/global/foo/newdir/new.txt", self.NEWFILE_CONTENTS)
|
||||
def _check(res):
|
||||
@ -667,6 +691,24 @@ class Web(WebMixin, unittest.TestCase):
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWDIRURL_replace(self):
|
||||
d = self.PUT("/vdrive/global/foo/sub?t=mkdir", "")
|
||||
def _check(res):
|
||||
self.failUnless("sub" in self._foo_node.children)
|
||||
newdir_uri = self._foo_node.children["sub"]
|
||||
newdir_node = self.nodes[newdir_uri]
|
||||
self.failIf(newdir_node.children)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWDIRURL_no_replace(self):
|
||||
d = self.PUT("/vdrive/global/foo/sub?t=mkdir&replace=false", "")
|
||||
d.addBoth(self.shouldFail, error.Error, "PUT_NEWDIRURL_no_replace",
|
||||
"409 Conflict",
|
||||
"There was already a child by that name, and you asked me "
|
||||
"to not replace it")
|
||||
return d
|
||||
|
||||
def test_PUT_NEWDIRURL_mkdirs(self):
|
||||
d = self.PUT("/vdrive/global/foo/subdir/newdir?t=mkdir", "")
|
||||
def _check(res):
|
||||
@ -1112,6 +1154,27 @@ class Web(WebMixin, unittest.TestCase):
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWFILEURL_uri_replace(self):
|
||||
new_uri = self.makefile(8)
|
||||
d = self.PUT("/vdrive/global/foo/bar.txt?t=uri", new_uri)
|
||||
def _check(res):
|
||||
self.failUnless("bar.txt" in self._foo_node.children)
|
||||
new_uri = self._foo_node.children["bar.txt"]
|
||||
new_contents = self.files[new_uri]
|
||||
self.failUnlessEqual(new_contents, self.files[new_uri])
|
||||
self.failUnlessEqual(res.strip(), new_uri)
|
||||
d.addCallback(_check)
|
||||
return d
|
||||
|
||||
def test_PUT_NEWFILEURL_uri_no_replace(self):
|
||||
new_uri = self.makefile(8)
|
||||
d = self.PUT("/vdrive/global/foo/bar.txt?t=uri&replace=false", new_uri)
|
||||
d.addBoth(self.shouldFail, error.Error, "PUT_NEWFILEURL_uri_no_replace",
|
||||
"409 Conflict",
|
||||
"There was already a child by that name, and you asked me "
|
||||
"to not replace it")
|
||||
return d
|
||||
|
||||
def test_XMLRPC(self):
|
||||
raise unittest.SkipTest("not yet")
|
||||
pass
|
||||
|
@ -330,6 +330,8 @@ class FileDownloader(resource.Resource):
|
||||
class BlockingFileError(Exception):
|
||||
"""We cannot auto-create a parent directory, because there is a file in
|
||||
the way"""
|
||||
class NoReplacementError(Exception):
|
||||
"""There was already a child by that name, and you asked me to not replace it"""
|
||||
|
||||
LOCALHOST = "127.0.0.1"
|
||||
|
||||
@ -549,8 +551,9 @@ class RenameForm(rend.Page):
|
||||
return ctx.tag
|
||||
|
||||
class POSTHandler(rend.Page):
|
||||
def __init__(self, node):
|
||||
def __init__(self, node, replace):
|
||||
self._node = node
|
||||
self._replace = replace
|
||||
|
||||
def renderHTTP(self, ctx):
|
||||
req = inevow.IRequest(ctx)
|
||||
@ -661,12 +664,13 @@ class DELETEHandler(rend.Page):
|
||||
return d
|
||||
|
||||
class PUTHandler(rend.Page):
|
||||
def __init__(self, node, path, t, localfile, localdir):
|
||||
def __init__(self, node, path, t, localfile, localdir, replace):
|
||||
self._node = node
|
||||
self._path = path
|
||||
self._t = t
|
||||
self._localfile = localfile
|
||||
self._localdir = localdir
|
||||
self._replace = replace
|
||||
|
||||
def renderHTTP(self, ctx):
|
||||
req = inevow.IRequest(ctx)
|
||||
@ -677,6 +681,7 @@ class PUTHandler(rend.Page):
|
||||
# we must traverse the path, creating new directories as necessary
|
||||
d = self._get_or_create_directories(self._node, self._path[:-1])
|
||||
name = self._path[-1]
|
||||
d.addCallback(self._check_replacement, name, self._replace)
|
||||
if t == "upload":
|
||||
if localfile:
|
||||
d.addCallback(self._upload_localfile, localfile, name)
|
||||
@ -698,6 +703,12 @@ class PUTHandler(rend.Page):
|
||||
req.setHeader("content-type", "text/plain")
|
||||
return str(f.value)
|
||||
d.addErrback(_check_blocking)
|
||||
def _check_replacement(f):
|
||||
f.trap(NoReplacementError)
|
||||
req.setResponseCode(http.CONFLICT)
|
||||
req.setHeader("content-type", "text/plain")
|
||||
return str(f.value)
|
||||
d.addErrback(_check_replacement)
|
||||
return d
|
||||
|
||||
def _get_or_create_directories(self, node, path):
|
||||
@ -716,6 +727,19 @@ class PUTHandler(rend.Page):
|
||||
d.addCallback(self._get_or_create_directories, path[1:])
|
||||
return d
|
||||
|
||||
def _check_replacement(self, node, name, replace):
|
||||
if replace:
|
||||
return node
|
||||
d = node.has_child(name)
|
||||
def _got(present):
|
||||
if present:
|
||||
raise NoReplacementError("There was already a child by that "
|
||||
"name, and you asked me to not "
|
||||
"replace it.")
|
||||
return node
|
||||
d.addCallback(_got)
|
||||
return d
|
||||
|
||||
def _mkdir(self, node, name):
|
||||
d = node.create_empty_directory(name)
|
||||
def _done(newnode):
|
||||
@ -852,6 +876,14 @@ class VDrive(rend.Page):
|
||||
return NeedLocalhostError(), ()
|
||||
# TODO: think about clobbering/revealing config files and node secrets
|
||||
|
||||
replace = True
|
||||
# if "replace" in req.fields:
|
||||
# if req.fields["replace"].value.lower() in ("false", "0"):
|
||||
# replace = False
|
||||
if "replace" in req.args:
|
||||
if req.args["replace"][0].lower() in ("false", "0"):
|
||||
replace = False
|
||||
|
||||
if method == "GET":
|
||||
# the node must exist, and our operation will be performed on the
|
||||
# node itself.
|
||||
@ -909,7 +941,7 @@ class VDrive(rend.Page):
|
||||
# node itself.
|
||||
d = self.get_child_at_path(path)
|
||||
def _got(node):
|
||||
return POSTHandler(node), ()
|
||||
return POSTHandler(node, replace), ()
|
||||
d.addCallback(_got)
|
||||
elif method == "DELETE":
|
||||
# the node must exist, and our operation will be performed on its
|
||||
@ -922,7 +954,7 @@ class VDrive(rend.Page):
|
||||
elif method in ("PUT",):
|
||||
# the node may or may not exist, and our operation may involve
|
||||
# all the ancestors of the node.
|
||||
return PUTHandler(self.node, path, t, localfile, localdir), ()
|
||||
return PUTHandler(self.node, path, t, localfile, localdir, replace), ()
|
||||
else:
|
||||
return rend.NotFound
|
||||
def _trap_KeyError(f):
|
||||
|
Loading…
x
Reference in New Issue
Block a user