Rev 5478: (mbp) show http error body text with pycurl (Martin Pool) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Oct 11 03:15:48 BST 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5478 [merge]
revision-id: pqm at pqm.ubuntu.com-20101011021544-4gewnsxq9vvjpggc
parent: pqm at pqm.ubuntu.com-20101010140708-2vk2se37najz1tzw
parent: mbp at sourcefrog.net-20101008101612-ue1yu0ihr1x6ndba
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2010-10-11 03:15:44 +0100
message:
  (mbp) show http error body text with pycurl (Martin Pool)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
  bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
  bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
=== modified file 'NEWS'
--- a/NEWS	2010-10-10 13:30:53 +0000
+++ b/NEWS	2010-10-11 02:15:44 +0000
@@ -115,6 +115,10 @@
   which is now deprecated.
   (Marius Kruger, #400554)
 
+* When using the pycurl client module, Bazaar shows some of the text from
+  http server error messages.
+  (Martin Pool, #656667)
+
 Documentation
 *************
 

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2010-10-08 07:13:14 +0000
+++ b/bzrlib/tests/__init__.py	2010-10-08 10:16:12 +0000
@@ -3882,6 +3882,7 @@
         'bzrlib.tests',
         'bzrlib.tests.fixtures',
         'bzrlib.timestamp',
+        'bzrlib.transport.http',
         'bzrlib.version_info_formats.format_custom',
         ]
 

=== modified file 'bzrlib/tests/test_transport.py'
--- a/bzrlib/tests/test_transport.py	2010-09-01 18:43:32 +0000
+++ b/bzrlib/tests/test_transport.py	2010-10-08 07:17:16 +0000
@@ -31,6 +31,7 @@
 from bzrlib.transport import (
     chroot,
     fakenfs,
+    http,
     local,
     memory,
     pathfilter,
@@ -993,3 +994,14 @@
         # And the rest are threads
         for t in started[1:]:
             t.join()
+
+
+class TestUnhtml(tests.TestCase):
+
+    """Tests for unhtml_roughly"""
+
+    def test_truncation(self):
+        fake_html = "<p>something!\n" * 1000
+        result = http.unhtml_roughly(fake_html)
+        self.assertEquals(len(result), 1000)
+        self.assertStartsWith(result, " something!")

=== modified file 'bzrlib/transport/http/__init__.py'
--- a/bzrlib/transport/http/__init__.py	2010-06-01 13:01:20 +0000
+++ b/bzrlib/transport/http/__init__.py	2010-10-08 07:17:16 +0000
@@ -666,3 +666,14 @@
     def _finished_reading(self):
         """See SmartClientMediumRequest._finished_reading."""
         pass
+
+
+def unhtml_roughly(maybe_html, length_limit=1000):
+    """Very approximate html->text translation, for presenting error bodies.
+
+    :param length_limit: Truncate the result to this many characters.
+
+    >>> unhtml_roughly("<b>bad</b> things happened\\n")
+    ' bad  things happened '
+    """
+    return re.subn(r"(<[^>]*>|\n|&nbsp;)", " ", maybe_html)[0][:length_limit]

=== modified file 'bzrlib/transport/http/_pycurl.py'
--- a/bzrlib/transport/http/_pycurl.py	2010-06-01 13:01:20 +0000
+++ b/bzrlib/transport/http/_pycurl.py	2010-10-08 04:38:25 +0000
@@ -44,6 +44,7 @@
     ca_bundle,
     HttpTransportBase,
     response,
+    unhtml_roughly,
     )
 
 try:
@@ -290,22 +291,36 @@
         return code, response.handle_response(abspath, code, msg, data)
 
 
-    def _raise_curl_http_error(self, curl, info=None):
+    def _raise_curl_http_error(self, curl, info=None, body=None):
+        """Common curl->bzrlib error translation.
+
+        Some methods may choose to override this for particular cases.
+
+        The URL and code are automatically included as appropriate.
+
+        :param info: Extra information to include in the message.
+        :param body: File-like object from which the body of the page can be read.
+        """
         code = curl.getinfo(pycurl.HTTP_CODE)
         url = curl.getinfo(pycurl.EFFECTIVE_URL)
-        # Some error codes can be handled the same way for all
-        # requests
+        if body is not None:
+            response_body = body.read()
+            plaintext_body = unhtml_roughly(response_body)
+        else:
+            response_body = None
+            plaintext_body = ''
         if code == 403:
             raise errors.TransportError(
                 'Server refuses to fulfill the request (403 Forbidden)'
-                ' for %s' % url)
+                ' for %s: %s' % (url, plaintext_body))
         else:
             if info is None:
                 msg = ''
             else:
                 msg = ': ' + info
             raise errors.InvalidHttpResponse(
-                url, 'Unable to handle http code %d%s' % (code,msg))
+                url, 'Unable to handle http code %d%s: %s' 
+                % (code, msg, plaintext_body))
 
     def _debug_cb(self, kind, text):
         if kind in (pycurl.INFOTYPE_HEADER_IN, pycurl.INFOTYPE_DATA_IN,




More information about the bazaar-commits mailing list