]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
web: /uri/ must escape slashes, we use bangs for this
authorBrian Warner <warner@lothar.com>
Sun, 8 Jul 2007 05:06:52 +0000 (22:06 -0700)
committerBrian Warner <warner@lothar.com>
Sun, 8 Jul 2007 05:06:52 +0000 (22:06 -0700)
docs/webapi.txt
src/allmydata/test/test_web.py
src/allmydata/uri.py
src/allmydata/webish.py

index dc445a17e9a319086e974422c042c3f0a7272c95..b5f6355f06ffd622d03892fef38ccbade47be800 100644 (file)
@@ -259,6 +259,12 @@ for files and directories which do not yet exist.
   would upload a file (with contents taken from the local filesystem) to a
   new file in a subdirectory of the referenced dirnode.
 
+  Note that since tahoe URIs may contain slashes (in particular, dirnode URIs
+  contain a FURL, which resembles a regular HTTP URL and starts with pb://),
+  when URIs are used in this form, they must be specially quoted. All slashes
+  in the URI must be replaced by '!' characters.
+
+
  PUT NEWFILEURL?t=uri
 
   This attaches a child (either a file or a directory) to the vdrive at the
@@ -277,6 +283,10 @@ for files and directories which do not yet exist.
   URI: unlike the GET /uri/$URI form, you cannot traverse to child nodes by
   appending additional path segments to the URL.
 
+  The $URI provided as a query argument is allowed to contain slashes. The
+  redirection provided will escape the slashes with exclamation points, as
+  described above.
+
 == XMLRPC ==
 
  http://localhost:8011/xmlrpc
index f20e5e3172dca02087dd30932b8f54ea4dda24cc..372094b0a3acdbaa86ac3bcb5fd00f72f5da6515 100644 (file)
@@ -69,7 +69,7 @@ class MyDirectoryNode(dirnode.MutableDirectoryNode):
         self._my_files = files
         self._my_client = client
         if uri is None:
-            uri = str(uri_counter.next())
+            uri = "URI:DIR:stuff/%s" % str(uri_counter.next())
         self._uri = str(uri)
         self._my_nodes[self._uri] = self
         self.children = {}
@@ -750,7 +750,7 @@ class Web(unittest.TestCase):
         return res
 
     def test_GET_URI_URL(self): # YES
-        base = "/uri/%s" % self._bar_txt_uri
+        base = "/uri/%s" % self._bar_txt_uri.replace("/","!")
         d = self.GET(base)
         d.addCallback(self.failUnlessIsBarDotTxt)
         d.addCallback(lambda res: self.GET(base+"?filename=bar.txt"))
@@ -760,11 +760,17 @@ class Web(unittest.TestCase):
         return d
 
     def test_GET_URI_URL_dir(self): # YES
-        base = "/uri/%s?t=json" % self._foo_uri
+        base = "/uri/%s?t=json" % self._foo_uri.replace("/","!")
         d = self.GET(base)
         d.addCallback(self.failUnlessIsFooJSON)
         return d
 
+    def test_GET_URI_URL_missing(self):
+        base = "/uri/missing?t=json"
+        d = self.GET(base)
+        d.addBoth(self.should404, "test_GET_URI_URL_missing")
+        return d
+
     def test_PUT_NEWFILEURL_uri(self): # YES
         new_uri = self.makefile(8)
         d = self.PUT("/vdrive/global/foo/new.txt?t=uri", new_uri)
index 80ff5b3c60776b4ef862258de4efbfd61980ee21..f50736d2ef35227c733c2d01010377fd851eb51a 100644 (file)
@@ -27,7 +27,7 @@ def pack_uri(storage_index, key, uri_extension_hash,
 
 
 def unpack_uri(uri):
-    assert uri.startswith("URI:")
+    assert uri.startswith("URI:"), uri
     d = {}
     (header,
      storage_index_s, key_s, uri_extension_hash_s,
index 7be898017addc739978986cb109278e52601a4a6..19a62c5f8acc61e1c5b0495fc755d9e38876d696 100644 (file)
@@ -101,11 +101,12 @@ class Directory(rend.Page):
             delete = "-"
         ctx.fillSlots("delete", delete)
 
+        uri_link = urllib.quote(target.get_uri().replace("/", "!"))
         childdata = [T.a(href="%s?t=json" % name)["JSON"], ", ",
                      T.a(href="%s?t=xml" % name)["XML"], ", ",
                      T.a(href="%s?t=uri" % name)["URI"], ", ",
                      T.a(href="%s?t=readonly-uri" % name)["readonly-URI"], ", ",
-                     T.a(href="/uri/%s" % target.get_uri())["URI-link"],
+                     T.a(href="/uri/%s" % uri_link)["URI-link"],
                      ]
         ctx.fillSlots("data", childdata)
 
@@ -846,19 +847,23 @@ class Root(rend.Page):
             d.addCallback(lambda vd: vd.locateChild(ctx, segments[2:]))
             return d
         elif segments[0] == "uri":
-            if len(segments) == 1:
+            if len(segments) == 1 or segments[1] == '':
                 if "uri" in req.args:
-                    uri = req.args["uri"][0]
+                    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) < 2:
                 return rend.NotFound
-            uri = segments[1]
+            uri = segments[1].replace("!", "/")
             d = vdrive.get_node(uri)
-            d.addCallback(lambda node: VDrive(node, "<from-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":
             pass # TODO