From: Brian Warner <warner@lothar.com>
Date: Sun, 27 Dec 2009 19:58:28 +0000 (-0500)
Subject: CLI: send 'Accept:' header to ask for text/plain tracebacks. Closes #646.
X-Git-Tag: trac-4200~62
X-Git-Url: https://git.rkrishnan.org/components/%22news.html/configuration.txt?a=commitdiff_plain;h=2e0a61a9539515fa41aff6573ab45bbb34555d8c;p=tahoe-lafs%2Ftahoe-lafs.git

CLI: send 'Accept:' header to ask for text/plain tracebacks. Closes #646.

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.
---

diff --git a/src/allmydata/scripts/common_http.py b/src/allmydata/scripts/common_http.py
index c62dfaec..cc145b02 100644
--- a/src/allmydata/scripts/common_http.py
+++ b/src/allmydata/scripts/common_http.py
@@ -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()
diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py
index 1801a8bd..2dfa2a9f 100644
--- a/src/allmydata/test/test_web.py
+++ b/src/allmydata/test/test_web.py
@@ -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