]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
add POST /uri?t=upload and tests thereof
authorZooko O'Whielacronx <zooko@zooko.com>
Fri, 7 Dec 2007 00:17:02 +0000 (17:17 -0700)
committerZooko O'Whielacronx <zooko@zooko.com>
Fri, 7 Dec 2007 00:17:02 +0000 (17:17 -0700)
Hm...  I refactored processing of segments in a way that I marked as "XXX HELP
I AM YUCKY", and then I ran out of time for rerefactoring it before I
committed.  At least all the tests pass.

src/allmydata/test/test_web.py
src/allmydata/webish.py

index 300018a27348bce263e89610826338a70b8e81c6..c3188b489b1f479d1a757c7d9e682799f9773eab 100644 (file)
@@ -14,7 +14,7 @@ from allmydata.interfaces import IURI, INewDirectoryURI, IReadonlyNewDirectoryUR
 # create a fake uploader/downloader, and a couple of fake dirnodes, then
 # create a webserver that works against them
 
-class MyClient(service.MultiService):
+class FakeClient(service.MultiService):
     nodeid = "fake_nodeid"
     basedir = "fake_basedir"
     def get_versions(self):
@@ -62,7 +62,7 @@ class MyClient(service.MultiService):
 
 class WebMixin(object):
     def setUp(self):
-        self.s = MyClient()
+        self.s = FakeClient()
         self.s.startService()
         self.ws = s = webish.WebishServer("0")
         s.allow_local_access(True)
@@ -799,6 +799,9 @@ class Web(WebMixin, unittest.TestCase):
         d.addCallback(_check)
         return d
 
+    def failUnlessCHKURIHasContents(self, got_uri, contents):
+        self.failUnless(FakeCHKFileNode.all_contents[got_uri] == contents)
+
     def test_PUT_NEWDIRURL_localdir(self):
         localdir = os.path.abspath("web/PUT_NEWDIRURL_localdir")
         # create some files there
@@ -888,6 +891,22 @@ class Web(WebMixin, unittest.TestCase):
                                                       self.NEWFILE_CONTENTS))
         return d
 
+    def test_POST_upload_no_link(self):
+        d = self.POST("/uri/", t="upload",
+                      file=("new.txt", self.NEWFILE_CONTENTS))
+        d.addCallback(self.failUnlessCHKURIHasContents, self.NEWFILE_CONTENTS)
+        return d
+
+    def test_POST_upload_no_link_whendone(self):
+        d = self.POST("/uri/", t="upload", when_done="/", 
+                      file=("new.txt", self.NEWFILE_CONTENTS))
+        d.addBoth(self.shouldRedirect, "/")
+        # XXX Test that resulting welcome page has a "most recent
+        # upload", the URI of which points to the file contents that
+        # you just uploaded.
+        return d
+    test_POST_upload_no_link_whendone.todo = "Not yet implemented."
+
     def test_POST_upload_mutable(self):
         # this creates a mutable file
         d = self.POST(self.public_url + "/foo", t="upload", mutable="true",
index 6353dbeb8faa73a92fb329f590d2d942ada5c2cd..84aa6ba4b71d758e841d2955d8d9d74021becb1d 100644 (file)
@@ -1210,6 +1210,33 @@ class URIPUTHandler(rend.Page):
         req.setHeader("content-type", "text/plain")
         return "/uri only accepts PUT and PUT?t=mkdir"
 
+class URIPOSTHandler(rend.Page):
+    def renderHTTP(self, ctx):
+        req = inevow.IRequest(ctx)
+        assert req.method == "POST"
+
+        t = ""
+        if "t" in req.args:
+            t = req.args["t"][0]
+
+        if t in ("", "upload"):
+            # "POST /uri", to create an unlinked file.
+            fileobj = req.fields["file"].file
+            uploadable = upload.FileHandle(fileobj)
+            d = IClient(ctx).upload(uploadable)
+            # that fires with the URI of the new file
+            return d
+
+        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())
+            return d
+
+        req.setResponseCode(http.BAD_REQUEST)
+        req.setHeader("content-type", "text/plain")
+        return "/uri accepts only PUT, PUT?t=mkdir, POST?t=upload" # XXX check this -- what about POST?t=mkdir?
+
 
 class Root(rend.Page):
 
@@ -1220,32 +1247,44 @@ class Root(rend.Page):
         client = IClient(ctx)
         req = inevow.IRequest(ctx)
 
-        if segments[0] == "uri":
-            if len(segments) == 1 or segments[1] == '':
-                if "uri" in req.args:
-                    uri = req.args["uri"][0].replace("/", "!")
-                    there = url.URL.fromContext(ctx)
-                    there = there.clear("uri")
-                    there = there.child("uri").child(uri)
-                    return there, ()
-            if len(segments) == 1 and req.method == "PUT":
-                # /uri
-                # either "PUT /uri" to create an unlinked file, or
-                # "PUT /uri?t=mkdir" to create an unlinked directory
-                return URIPUTHandler(), ()
-            if len(segments) < 2:
-                return rend.NotFound
-            uri = segments[1].replace("!", "/")
-            d = defer.maybeDeferred(client.create_node_from_uri, uri)
-            d.addCallback(lambda node: VDrive(node, "from-uri"))
-            d.addCallback(lambda vd: vd.locateChild(ctx, segments[2:]))
-            def _trap_KeyError(f):
-                f.trap(KeyError)
-                return rend.FourOhFour(), ()
-            d.addErrback(_trap_KeyError)
-            return d
-        elif segments[0] == "xmlrpc":
-            raise NotImplementedError()
+        segments = list(segments) # XXX HELP I AM YUCKY!
+        while segments and not segments[-1]:
+            segments.pop()
+        if not segments:
+            segments.append('')
+        segments = tuple(segments)
+        if segments:
+            if segments[0] == "uri":
+                if len(segments) == 1 or segments[1] == '':
+                    if "uri" in req.args:
+                        uri = req.args["uri"][0].replace("/", "!")
+                        there = url.URL.fromContext(ctx)
+                        there = there.clear("uri")
+                        there = there.child("uri").child(uri)
+                        return there, ()
+                if len(segments) == 1:
+                    # /uri
+                    if req.method == "PUT":
+                        # either "PUT /uri" to create an unlinked file, or
+                        # "PUT /uri?t=mkdir" to create an unlinked directory
+                        return URIPUTHandler(), ()
+                    elif req.method == "POST":
+                        # "POST /uri?t=upload&file=newfile" to upload an unlinked
+                        # file
+                        return URIPOSTHandler(), ()
+                if len(segments) < 2:
+                    return rend.NotFound
+                uri = segments[1].replace("!", "/")
+                d = defer.maybeDeferred(client.create_node_from_uri, uri)
+                d.addCallback(lambda node: VDrive(node, "from-uri"))
+                d.addCallback(lambda vd: vd.locateChild(ctx, segments[2:]))
+                def _trap_KeyError(f):
+                    f.trap(KeyError)
+                    return rend.FourOhFour(), ()
+                d.addErrback(_trap_KeyError)
+                return d
+            elif segments[0] == "xmlrpc":
+                raise NotImplementedError()
         return rend.Page.locateChild(self, ctx, segments)
 
     child_webform_css = webform.defaultCSS