]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
webish: implement 'PUT /uri' (to create anonymous files)
authorBrian Warner <warner@allmydata.com>
Thu, 6 Sep 2007 00:12:27 +0000 (17:12 -0700)
committerBrian Warner <warner@allmydata.com>
Thu, 6 Sep 2007 00:12:27 +0000 (17:12 -0700)
src/allmydata/test/test_web.py
src/allmydata/webish.py

index d9e61384a237908eca525daad60fe904acb827e8..c691a682c80bb1a04596856a472621bdda84e638 100644 (file)
@@ -62,8 +62,9 @@ def make_newuri(data):
 class MyUploader(service.Service):
     implements(interfaces.IUploader)
     name = "uploader"
-    def __init__(self, files):
+    def __init__(self, files, nodes):
         self.files = files
+        self.nodes = nodes
 
     def upload(self, uploadable):
         d = uploadable.get_size()
@@ -72,7 +73,9 @@ class MyUploader(service.Service):
         def _got_data(data):
             newuri = make_newuri(data)
             self.files[newuri] = data
+            self.nodes[newuri] = MyFileNode(newuri, self.parent)
             uploadable.close()
+            return newuri
         d.addCallback(_got_data)
         return d
 
@@ -173,7 +176,7 @@ class WebMixin(object):
 
         dl = MyDownloader(self.files)
         dl.setServiceParent(self.s)
-        ul = MyUploader(self.files)
+        ul = MyUploader(self.files, self.nodes)
         ul.setServiceParent(self.s)
 
         v.public_root = self.makedir()
@@ -1389,6 +1392,20 @@ class Web(WebMixin, unittest.TestCase):
                   "to not replace it")
         return d
 
+    def test_PUT_NEWFILE_URI(self):
+        file_contents = "New file contents here\n"
+        d = self.PUT("/uri", file_contents)
+        def _check(uri):
+            self.failUnless(uri in self.files)
+            self.failUnless(uri in self.nodes)
+            self.failUnlessEqual(self.files[uri], file_contents)
+            return self.GET("/uri/%s" % uri.replace("/","!"))
+        d.addCallback(_check)
+        def _check2(res):
+            self.failUnlessEqual(res, file_contents)
+        d.addCallback(_check2)
+        return d
+
     def test_XMLRPC(self):
         raise unittest.SkipTest("not yet")
         pass
index 2801270db14a29dd538335df2bd500b01fb50dbb..6d1fa382976ff1960c1b64de289f649b6b85af8b 100644 (file)
@@ -1019,6 +1019,36 @@ class VDrive(rend.Page):
         d.addErrback(_trap_KeyError)
         return d
 
+class URIPUTHandler(rend.Page):
+    def renderHTTP(self, ctx):
+        req = inevow.IRequest(ctx)
+        assert req.method == "PUT"
+
+        t = ""
+        if "t" in req.args:
+            t = req.args["t"][0]
+
+        if t == "":
+            # "PUT /uri", to create an unlinked file. This is like PUT but
+            # without the associated set_uri.
+            uploadable = upload.FileHandle(req.content)
+            uploader = IClient(ctx).getServiceNamed("uploader")
+            d = uploader.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. We use the
+            # public vdriveserver to create the dirnode.
+            vdrive = IClient(ctx).getServiceNamed("vdrive")
+            d = vdrive.create_directory()
+            d.addCallback(lambda dirnode: dirnode.get_uri())
+            return d
+
+        req.setResponseCode(http.BAD_REQUEST)
+        req.setHeader("content-type", "text/plain")
+        return "/uri only accepts PUT"
+
 
 class Root(rend.Page):
 
@@ -1049,6 +1079,11 @@ class Root(rend.Page):
                     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("!", "/")