]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
webapi: don't allow ETags in t=info or t=rename-form, both are variable
authorBrian Warner <warner@lothar.com>
Sun, 13 May 2012 07:41:53 +0000 (00:41 -0700)
committerBrian Warner <warner@lothar.com>
Sun, 13 May 2012 07:45:11 +0000 (00:45 -0700)
t=info contains randomly-generated ophandles, and t=rename-form contains the
name of the child being renamed, so neither is eligible for a
short-circuiting ETag. Enhanced test_web to exercise this. Had to improve
FakeCHKFileNode slightly to let it participate. Refs #443.

src/allmydata/test/common.py
src/allmydata/test/test_web.py
src/allmydata/web/directory.py
src/allmydata/web/filenode.py

index 627765a4c4d2183e8110e7f14313c05b0e6e1594..a914baa8738c5ea028c71b32dcf747c2864a0133 100644 (file)
@@ -113,6 +113,8 @@ class FakeCHKFileNode:
         except KeyError, le:
             raise NotEnoughSharesError(le, 0, 3)
         return len(data)
+    def get_current_size(self):
+        return defer.succeed(self.get_size())
 
     def read(self, consumer, offset=0, size=None):
         # we don't bother to call registerProducer/unregisterProducer,
index 81dbb2015f420a0fd5f9d9c056224f4e56bcec19..1b1508287bf9a71c5073a0806f4bac1b6538c13d 100644 (file)
@@ -930,6 +930,10 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
         (newkids, caps) = self._create_immutable_children()
         d = self.POST2(self.public_url + "/foo/newdir?t=mkdir-immutable",
                       simplejson.dumps(newkids))
+        def _stash_immdir_uri(uri):
+            self._immdir_uri = uri
+            return uri
+        d.addCallback(_stash_immdir_uri)
         d.addCallback(_check_etags)
 
         # Check that etags work with immutable files
@@ -951,6 +955,33 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
                           self.failUnlessEqual(int(code), http.NOT_MODIFIED))
             return d
         d.addCallback(_check_match)
+
+        def _no_etag(uri, t):
+            target = "/uri/%s?t=%s" % (uri, t)
+            d = self.GET(target, return_response=True, followRedirect=True)
+            d.addCallback(lambda (data, code, headers):
+                          self.failIf("etag" in headers, target))
+            return d
+        def _yes_etag(uri, t):
+            target = "/uri/%s?t=%s" % (uri, t)
+            d = self.GET(target, return_response=True, followRedirect=True)
+            d.addCallback(lambda (data, code, headers):
+                          self.failUnless("etag" in headers, target))
+            return d
+
+        d.addCallback(lambda ign: _yes_etag(self._bar_txt_uri, ""))
+        d.addCallback(lambda ign: _yes_etag(self._bar_txt_uri, "json"))
+        d.addCallback(lambda ign: _yes_etag(self._bar_txt_uri, "uri"))
+        d.addCallback(lambda ign: _yes_etag(self._bar_txt_uri, "readonly-uri"))
+        d.addCallback(lambda ign: _no_etag(self._bar_txt_uri, "info"))
+
+        d.addCallback(lambda ign: _yes_etag(self._immdir_uri, ""))
+        d.addCallback(lambda ign: _yes_etag(self._immdir_uri, "json"))
+        d.addCallback(lambda ign: _yes_etag(self._immdir_uri, "uri"))
+        d.addCallback(lambda ign: _yes_etag(self._immdir_uri, "readonly-uri"))
+        d.addCallback(lambda ign: _no_etag(self._immdir_uri, "info"))
+        d.addCallback(lambda ign: _no_etag(self._immdir_uri, "rename-form"))
+
         return d
 
     # TODO: version of this with a Unicode filename
index 80f5aa3deb4d41e3eb620c7f578fb1a5381f57e3..cf1d4d38ce3bf47d03bc35f46a57c8cd44059525 100644 (file)
@@ -154,7 +154,10 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
         # This is where all of the directory-related ?t=* code goes.
         t = get_arg(req, "t", "").strip()
 
-        if not self.node.is_mutable():
+        # t=info contains variable ophandles, t=rename-form contains the name
+        # of the child being renamed. Neither is allowed an ETag.
+        FIXED_OUTPUT_TYPES =  ["", "json", "uri", "readonly-uri"]
+        if not self.node.is_mutable() and t in FIXED_OUTPUT_TYPES:
             si = self.node.get_storage_index()
             if si and req.setETag('DIR:%s-%s' % (base32.b2a(si), t or "")):
                 return ""
index 9a1983e6b7a72db6c934be9a90dbc365ab7c16db..bce8e90cd1727ce3fa9c8f941465c748ce43549d 100644 (file)
@@ -158,7 +158,9 @@ class FileNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
         req = IRequest(ctx)
         t = get_arg(req, "t", "").strip()
 
-        if not self.node.is_mutable():
+        # t=info contains variable ophandles, so is not allowed an ETag.
+        FIXED_OUTPUT_TYPES = ["", "json", "uri", "readonly-uri"]
+        if not self.node.is_mutable() and t in FIXED_OUTPUT_TYPES:
             # if the client already has the ETag then we can
             # short-circuit the whole process.
             si = self.node.get_storage_index()