From a4bc623fa54db4a061f7ab4b95d68c8e4aa9aa4a Mon Sep 17 00:00:00 2001 From: Zooko O'Whielacronx Date: Thu, 20 Dec 2007 12:58:17 -0700 Subject: [PATCH] make the wapi/wui [*] support creation of a new directory without there already being an existing directory to link the new one into [*] WebAPI/WebUI --- src/allmydata/test/test_web.py | 27 +++++++++++++++++++-------- src/allmydata/webish.py | 21 +++++++++++++++++---- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index fb0b3b10..5e87e375 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -1109,6 +1109,11 @@ class Web(WebMixin, unittest.TestCase): d.addCallback(_after_mkdir) return d + def test_POST_mkdir_no_parentdir_redirect(self): + d = self.POST("/uri/?t=mkdir&redirect_to_result=true") + d.addBoth(self.shouldRedirect, None, statuscode='303') + return d + def test_POST_mkdir_replace(self): # return value? d = self.POST(self.public_url + "/foo", t="mkdir", name="sub") d.addCallback(lambda res: self._foo_node.get("sub")) @@ -1301,15 +1306,21 @@ class Web(WebMixin, unittest.TestCase): d.addCallback(self.failUnlessIsFooJSON) return d - def shouldRedirect(self, res, target): + def shouldRedirect(self, res, target=None, statuscode=None): + """ If target is not None then the redirection has to go to target. If + statuscode is not None then the redirection has to be accomplished with + that HTTP status code.""" if not isinstance(res, failure.Failure): - self.fail("we were expecting to get redirected to %s, not get an" - " actual page: %s" % (target, res)) + self.fail("we were expecting to get redirected %s, not get an" + " actual page: %s" % ((target is None) and "somewhere" or ("to " + target), res)) res.trap(error.PageRedirect) - # the PageRedirect does not seem to capture the uri= query arg - # properly, so we can't check for it. - realtarget = self.webish_url + target - self.failUnlessEqual(res.value.location, realtarget) + if statuscode is not None: + self.failUnlessEqual(res.value.status, statuscode) + if target is not None: + # the PageRedirect does not seem to capture the uri= query arg + # properly, so we can't check for it. + realtarget = self.webish_url + target + self.failUnlessEqual(res.value.location, realtarget) def test_GET_URI_form(self): base = "/uri?uri=%s" % self._bar_txt_uri @@ -1422,7 +1433,7 @@ class Web(WebMixin, unittest.TestCase): "/uri only accepts PUT and PUT?t=mkdir") return d - def test_PUT_NEWDIR_URI(self): + def test_PUT_mkdir(self): d = self.PUT("/uri?t=mkdir", "") def _check(uri): n = self.s.create_node_from_uri(uri.strip()) diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index b3169704..91539c8b 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -30,6 +30,9 @@ class ILocalAccess(Interface): """Return True if t=upload&localdir= is allowed, giving anyone who can talk to the webserver control over the local (disk) filesystem.""" +def boolean_of_arg(arg): + assert arg.lower() in ("true", "t", "1", "false", "f", "0") + return arg.lower() in ("true", "t", "1") # we must override twisted.web.http.Request.requestReceived with a version # that doesn't use cgi.parse_multipart() . Since we actually use Nevow, we @@ -720,7 +723,7 @@ class POSTHandler(rend.Page): when_done = req.fields["when_done"].value if "replace" in req.fields: - if req.fields["replace"].value.lower() in ("false", "0"): + if not boolean_of_arg(req.fields["replace"].value): self._replace = False if t == "mkdir": @@ -1105,7 +1108,7 @@ class VDrive(rend.Page): replace = True if "replace" in req.args: - if req.args["replace"][0].lower() in ("false", "0"): + if not boolean_of_arg(req.args["replace"][0]): replace = False if method == "GET": @@ -1209,6 +1212,7 @@ class URIPUTHandler(rend.Page): # "PUT /uri?t=mkdir", to create an unlinked directory. d = IClient(ctx).create_empty_dirnode() d.addCallback(lambda dirnode: dirnode.get_uri()) + # XXX add redirect_to_result return d req.setResponseCode(http.BAD_REQUEST) @@ -1235,7 +1239,16 @@ class URIPOSTHandler(rend.Page): if t == "mkdir": # "PUT /uri?t=mkdir", to create an unlinked directory. d = IClient(ctx).create_empty_dirnode() - d.addCallback(lambda dirnode: dirnode.get_uri()) + redirect = req.args.has_key("redirect_to_result") and boolean_of_arg(req.args["redirect_to_result"][0]) + if redirect: + def _then_redir(res): + req.setResponseCode(303) + req.setHeader('location', res.get_uri()) + req.finish() + return '' + d.addCallback(_then_redir) + else: + d.addCallback(lambda dirnode: dirnode.get_uri()) return d req.setResponseCode(http.BAD_REQUEST) @@ -1275,7 +1288,7 @@ class Root(rend.Page): return URIPUTHandler(), () elif req.method == "POST": # "POST /uri?t=upload&file=newfile" to upload an unlinked - # file + # file or "POST /uri?t=mkdir" to create a new directory return URIPOSTHandler(), () if len(segments) < 2: return rend.NotFound -- 2.45.2