CLI: send 'Accept:' header to ask for text/plain tracebacks. Closes #646.
authorBrian Warner <warner@lothar.com>
Sun, 27 Dec 2009 19:58:28 +0000 (14:58 -0500)
committerBrian Warner <warner@lothar.com>
Sun, 27 Dec 2009 19:58:28 +0000 (14:58 -0500)
The webapi has been looking for an Accept header since 1.4.0, but it treats a
missing header as equal to */* (to honor RFC2616). This change finally
modifies our CLI tools to ask for "text/plain, application/octet-stream",
which seems roughly correct (we either want a plain-text traceback or error
message, or an uninterpreted chunk of binary data to save to disk). Some day
we'll figure out how JSON fits into this scheme.

src/allmydata/scripts/common_http.py
src/allmydata/test/test_web.py

index c62dfaec4fa5ec82cf4ea9d0b92104986fde4cb3..cc145b02a2cdba62c8c00a899ed00eb057cb755d 100644 (file)
@@ -45,6 +45,7 @@ def do_http(method, url, body=""):
     c.putrequest(method, path)
     c.putheader("Hostname", host)
     c.putheader("User-Agent", allmydata.__full_version__ + " (tahoe-client)")
+    c.putheader("Accept", "text/plain, application/octet-stream")
     c.putheader("Connection", "close")
 
     old = body.tell()
index 1801a8bdee3d1714ceff39d34463d5e2734f525f..2dfa2a9f65521f40646936bab10352de2dd0a844 100644 (file)
@@ -3693,29 +3693,48 @@ class Grid(GridTestMixin, WebErrorMixin, unittest.TestCase, ShouldFailMixin):
         w = c0.getServiceNamed("webish")
         w.root.putChild("ERRORBOOM", ErrorBoom())
 
+        # "Accept: */*" :        should get a text/html stack trace
+        # "Accept: text/plain" : should get a text/plain stack trace
+        # "Accept: text/plain, application/octet-stream" : text/plain (CLI)
+        # no Accept header:      should get a text/html stack trace
+
         d.addCallback(lambda ignored:
                       self.shouldHTTPError("GET errorboom_html",
                                            500, "Internal Server Error", None,
-                                           self.GET, "ERRORBOOM"))
-        def _internal_error_html(body):
-            # test that a weird exception during a webapi operation with
-            # Accept:*/* results in a text/html stack trace, while one
-            # without that Accept: line gets us a text/plain stack trace
+                                           self.GET, "ERRORBOOM",
+                                           headers={"accept": ["*/*"]}))
+        def _internal_error_html1(body):
             self.failUnless("<html>" in body, "expected HTML, not '%s'" % body)
-        d.addCallback(_internal_error_html)
+        d.addCallback(_internal_error_html1)
 
         d.addCallback(lambda ignored:
                       self.shouldHTTPError("GET errorboom_text",
                                            500, "Internal Server Error", None,
                                            self.GET, "ERRORBOOM",
                                            headers={"accept": ["text/plain"]}))
-        def _internal_error_text(body):
-            # test that a weird exception during a webapi operation with
-            # Accept:*/* results in a text/html stack trace, while one
-            # without that Accept: line gets us a text/plain stack trace
+        def _internal_error_text2(body):
+            self.failIf("<html>" in body, body)
+            self.failUnless(body.startswith("Traceback "), body)
+        d.addCallback(_internal_error_text2)
+
+        CLI_accepts = "text/plain, application/octet-stream"
+        d.addCallback(lambda ignored:
+                      self.shouldHTTPError("GET errorboom_text",
+                                           500, "Internal Server Error", None,
+                                           self.GET, "ERRORBOOM",
+                                           headers={"accept": [CLI_accepts]}))
+        def _internal_error_text3(body):
             self.failIf("<html>" in body, body)
             self.failUnless(body.startswith("Traceback "), body)
-        d.addCallback(_internal_error_text)
+        d.addCallback(_internal_error_text3)
+
+        d.addCallback(lambda ignored:
+                      self.shouldHTTPError("GET errorboom_text",
+                                           500, "Internal Server Error", None,
+                                           self.GET, "ERRORBOOM"))
+        def _internal_error_html4(body):
+            self.failUnless("<html>" in body, "expected HTML, not '%s'" % body)
+        d.addCallback(_internal_error_html4)
 
         def _flush_errors(res):
             # Trial: please ignore the CompletelyUnhandledError in the logs