web: /uri/ must escape slashes, we use bangs for this

This commit is contained in:
Brian Warner 2007-07-07 22:06:52 -07:00
parent fb40b55bc3
commit 62e8528cc6
4 changed files with 30 additions and 9 deletions

View 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

View 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)

View 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,

View 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