add 'web.ambient_upload_authority' as a paramater to tahoe.cfg
authortoby.murray <toby.murray>
Sun, 18 Jan 2009 17:54:30 +0000 (10:54 -0700)
committertoby.murray <toby.murray>
Sun, 18 Jan 2009 17:54:30 +0000 (10:54 -0700)
src/allmydata/client.py
src/allmydata/test/common.py
src/allmydata/test/test_ambient_upload_authority.py [new file with mode: 0644]
src/allmydata/web/root.py
src/allmydata/webish.py

index 41c2f7e7e06861d7561f50a31025faa5f2e8daf5..20fab7b063fc5ce4984b7f4f49e7fa42daef780e 100644 (file)
@@ -267,7 +267,9 @@ class Client(node.Node, pollmixin.PollMixin):
         nodeurl_path = os.path.join(self.basedir, "node.url")
         staticdir = self.get_config("node", "web.static", "public_html")
         staticdir = os.path.expanduser(staticdir)
-        ws = WebishServer(webport, nodeurl_path, staticdir)
+        # should we provide ambient upload authority?
+        ambientUploadAuthority = self.get_config("node", "web.ambient_upload_authority", True, boolean=True)
+        ws = WebishServer(webport, nodeurl_path, staticdir, ambientUploadAuthority)
         self.add_service(ws)
 
     def init_ftp_server(self):
index 29fcb9e3ca3d4bf2d5762dd454928e4f1274b95f..6fbe3b28de9136f0d933afb170f2a73a0b9457e0 100644 (file)
@@ -437,9 +437,10 @@ class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin):
             helper_furl = f.read()
             f.close()
             self.helper_furl = helper_furl
-            f = open(os.path.join(basedirs[3],"helper.furl"), "w")
-            f.write(helper_furl)
-            f.close()
+            if self.numclients >= 4:
+                f = open(os.path.join(basedirs[3],"helper.furl"), "w")
+                f.write(helper_furl)
+                f.close()
 
             # this starts the rest of the clients
             for i in range(1, self.numclients):
@@ -454,10 +455,11 @@ class SystemTestMixin(pollmixin.PollMixin, testutil.StallMixin):
             l = self.clients[0].getServiceNamed("webish").listener
             port = l._port.getHost().port
             self.webish_url = "http://localhost:%d/" % port
-            # and the helper-using webport
-            l = self.clients[3].getServiceNamed("webish").listener
-            port = l._port.getHost().port
-            self.helper_webish_url = "http://localhost:%d/" % port
+            if self.numclients >=4:
+                # and the helper-using webport
+                l = self.clients[3].getServiceNamed("webish").listener
+                port = l._port.getHost().port
+                self.helper_webish_url = "http://localhost:%d/" % port
         d.addCallback(_connected)
         return d
 
diff --git a/src/allmydata/test/test_ambient_upload_authority.py b/src/allmydata/test/test_ambient_upload_authority.py
new file mode 100644 (file)
index 0000000..9c4d9a2
--- /dev/null
@@ -0,0 +1,97 @@
+import os
+
+from twisted.trial import unittest
+from twisted.internet import defer, reactor
+from twisted.python import log
+from twisted.web import client, http
+
+from allmydata.test.common import SystemTestMixin
+
+
+class TestCase(SystemTestMixin, unittest.TestCase):
+
+    def setAmbientUploadAuthority(self,ambientUploadAuthority):
+        self.ambientUploadAuthority = ambientUploadAuthority
+
+    def _test_ambient_upload_authority(self):
+        self.webip = "127.0.0.1" 
+        self.webport = 3456
+        self.basedir = self.mktemp()
+
+        # set up an introducer and a node
+        d = self.set_up_nodes(1)
+        d.addCallback(self._test_ambient_upload_authority2)                
+        d.addErrback(self.fail)
+        return d
+
+    def _set_up_nodes_extra_config(self):
+        # we need to remove the 'webport' old-style config file
+        # or else the node won't start 
+        os.remove(os.path.join(self.getdir("client0"), "webport"))
+        f = open(os.path.join(self.getdir("client0"), "tahoe.cfg"), "wt")
+        f.write("\n")
+        f.write("[node]\n")
+        f.write("web.ambient_upload_authority = %s\n" % ("false","true")[self.ambientUploadAuthority])
+        f.write("web.port = tcp:%d:interface=%s\n" % (self.webport, self.webip))
+        f.write("\n")
+        f.write("[client]\n")
+        f.write("introducer.furl = %s\n" % self.introducer_furl)
+        f.write("\n")
+        f.write("[storage]\n")
+        f.write("enabled = true\n")
+        f.write("\n")
+        f.close()
+        
+        
+    def _test_ambient_upload_authority2(self, ignored=None):
+        content_type = 'multipart/form-data; boundary=----------ThIs_Is_tHe_bouNdaRY_$'
+        body = '------------ThIs_Is_tHe_bouNdaRY_$\r\nContent-Disposition: form-data; name="t"\r\n\r\nupload\r\n------------ThIs_Is_tHe_bouNdaRY_$\r\nContent-Disposition: form-data; name="file"; filename="file1.txt"\r\nContent-Type: application/octet-stream\r\n\r\nsome test text\r\n------------ThIs_Is_tHe_bouNdaRY_$--\r\n'
+        headers = {'Content-Type': content_type,
+                   'Content-Length': len(body)}
+
+        deferreds = []
+        expected = (http.BAD_REQUEST, http.OK)[self.ambientUploadAuthority]
+
+        # try to upload using the local web client
+        def tryRequest(pathetc, method, postdata=None, headers=None):
+            url = "http://%s:%d/%s" % (self.webip, self.webport, pathetc)
+            f = client.HTTPClientFactory(url,method, postdata, headers)
+            f.deferred.addCallback(self._cbCheckResponse,[f,expected])
+            f.deferred.addErrback(self._cbCheckResponse,[f,expected])
+            deferreds.append(f.deferred)
+            reactor.connectTCP(self.webip, self.webport, f)
+        
+        tryRequest("uri","PUT","non contents\r\n")
+        tryRequest("uri?t=mkdir","PUT")
+        tryRequest("uri?t=mkdir","POST")
+        tryRequest("uri?t=upload","POST",body,headers)
+
+        # give us one deferred that will fire iff all of the above succeed
+        dlist = defer.DeferredList(deferreds,fireOnOneCallback=False,
+                                   fireOnOneErrback=True)
+        dlist.addErrback(self.fail)
+
+        return dlist
+
+    def _cbCheckResponse(self, ignored, cmp):
+        r = cmp[0]
+        expected = cmp[1]
+        self.failUnless(int(r.status) == expected)
+        
+        
+class TestAmbientUploadAuthorityEnabled(TestCase):
+    def setUp(self):
+        TestCase.setUp(self)
+        self.setAmbientUploadAuthority(True)
+
+    def test_ambient_upload_authority_enabled(self):
+        return self._test_ambient_upload_authority()
+
+class TestAmbientUploadAuthorityDisabled(TestCase):
+    def setUp(self):
+        TestCase.setUp(self)
+        self.setAmbientUploadAuthority(False)
+
+    def test_ambient_upload_authority_disabled(self):
+        return self._test_ambient_upload_authority()
+
index 603c27ffc52bb8bcf6ed4ce9114ff1e6aec82ec0..7413b1329c534f7aaab06eb4563a81677144fddb 100644 (file)
@@ -22,6 +22,9 @@ from allmydata.web.common import abbreviate_size, IClient, \
 class URIHandler(RenderMixin, rend.Page):
     # I live at /uri . There are several operations defined on /uri itself,
     # mostly involved with creation of unlinked files and directories.
+    
+    def setAmbientUploadAuthority(self, ambientUploadAuthority):
+        self.ambientUploadAuthority = ambientUploadAuthority
 
     def render_GET(self, ctx):
         req = IRequest(ctx)
@@ -36,6 +39,9 @@ class URIHandler(RenderMixin, rend.Page):
         return there
 
     def render_PUT(self, ctx):
+        if not self.ambientUploadAuthority:
+            raise WebError("/uri handling of PUT not enabled on this node")
+
         req = IRequest(ctx)
         # either "PUT /uri" to create an unlinked file, or
         # "PUT /uri?t=mkdir" to create an unlinked directory
@@ -53,6 +59,9 @@ class URIHandler(RenderMixin, rend.Page):
         raise WebError(errmsg, http.BAD_REQUEST)
 
     def render_POST(self, ctx):
+        if not self.ambientUploadAuthority:
+            raise WebError("/uri handling of POST not enabled on this node")
+
         # "POST /uri?t=upload&file=newfile" to upload an
         # unlinked file or "POST /uri?t=mkdir" to create a
         # new directory
@@ -122,6 +131,9 @@ class Root(rend.Page):
         rend.Page.__init__(self, original)
         self.child_operations = operations.OphandleTable()
 
+    def setAmbientUploadAuthority(self, ambientUploadAuthority):
+        self.child_uri.setAmbientUploadAuthority(ambientUploadAuthority)
+
     child_uri = URIHandler()
     child_cap = URIHandler()
     child_file = FileHandler()
index 14c623139c75730a141ab6ddf654f121a9a45069..74e5ba4378a65913e61d3dcbd96ef73f87ea0782 100644 (file)
@@ -123,10 +123,13 @@ class WebishServer(service.MultiService):
     name = "webish"
     root_class = root.Root
 
-    def __init__(self, webport, nodeurl_path=None, staticdir=None):
+    def __init__(self, webport, nodeurl_path=None, staticdir=None, 
+                 ambientUploadAuthority=False):
         service.MultiService.__init__(self)
         self.webport = webport
         self.root = self.root_class()
+        if self.root_class == root.Root:
+            self.root.setAmbientUploadAuthority(ambientUploadAuthority)
         self.site = site = appserver.NevowSite(self.root)
         self.site.requestFactory = MyRequest
         if self.root.child_operations: