From de14791caf52ddf81999ae27d168344eacabf5ae Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@lothar.com>
Date: Wed, 20 Jan 2010 22:50:52 -0800
Subject: [PATCH] Fix webapi t=mkdir with multpart/form-data, as on the Welcome
 page. Closes #919.

---
 src/allmydata/test/test_web.py | 19 +++++++++++++++++++
 src/allmydata/web/unlinked.py  | 19 +++++++++++++------
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py
index bb986521..d4f4bb53 100644
--- a/src/allmydata/test/test_web.py
+++ b/src/allmydata/test/test_web.py
@@ -2040,6 +2040,15 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, unittest.TestCase):
         d.addCallback(_after_mkdir)
         return d
 
+    def test_POST_mkdir_no_parentdir_noredirect2(self):
+        # make sure form-based arguments (as on the welcome page) still work
+        d = self.POST("/uri", t="mkdir")
+        def _after_mkdir(res):
+            uri.DirectoryURI.init_from_string(res)
+        d.addCallback(_after_mkdir)
+        d.addErrback(self.explain_web_error)
+        return d
+
     def test_POST_mkdir_no_parentdir_redirect(self):
         d = self.POST("/uri?t=mkdir&redirect_to_result=true")
         d.addBoth(self.shouldRedirect, None, statuscode='303')
@@ -2049,6 +2058,16 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, unittest.TestCase):
         d.addCallback(_check_target)
         return d
 
+    def test_POST_mkdir_no_parentdir_redirect2(self):
+        d = self.POST("/uri", t="mkdir", redirect_to_result="true")
+        d.addBoth(self.shouldRedirect, None, statuscode='303')
+        def _check_target(target):
+            target = urllib.unquote(target)
+            self.failUnless(target.startswith("uri/URI:DIR2:"), target)
+        d.addCallback(_check_target)
+        d.addErrback(self.explain_web_error)
+        return d
+
     def _create_initial_children(self):
         contents, n, filecap1 = self.makefile(12)
         md1 = {"metakey1": "metavalue1"}
diff --git a/src/allmydata/web/unlinked.py b/src/allmydata/web/unlinked.py
index 70faab96..670aff68 100644
--- a/src/allmydata/web/unlinked.py
+++ b/src/allmydata/web/unlinked.py
@@ -91,12 +91,19 @@ def POSTUnlinkedSSK(req, client):
 
 def POSTUnlinkedCreateDirectory(req, client):
     # "POST /uri?t=mkdir", to create an unlinked directory.
-    req.content.seek(0)
-    kids_json = req.content.read()
-    if kids_json:
-        raise WebError("t=mkdir does not accept children=, "
-                       "try t=mkdir-with-children instead",
-                       http.BAD_REQUEST)
+    ct = req.getHeader("content-type") or ""
+    if not ct.startswith("multipart/form-data"):
+        # guard against accidental attempts to call t=mkdir as if it were
+        # t=mkdir-with-children, but make sure we tolerate the usual HTML
+        # create-directory form (in which the t=mkdir and redirect_to_result=
+        # and other arguments can be passed encoded as multipath/form-data,
+        # in the request body).
+        req.content.seek(0)
+        kids_json = req.content.read()
+        if kids_json:
+            raise WebError("t=mkdir does not accept children=, "
+                           "try t=mkdir-with-children instead",
+                           http.BAD_REQUEST)
     d = client.create_dirnode()
     redirect = get_arg(req, "redirect_to_result", "false")
     if boolean_of_arg(redirect):
-- 
2.45.2