Rev 3539: (awilkins) Fix #247585 and support IIS in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Jul 15 15:53:11 BST 2008


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

------------------------------------------------------------
revno: 3539
revision-id:pqm at pqm.ubuntu.com-20080715145300-6ok29w4tk922f7b3
parent: pqm at pqm.ubuntu.com-20080715141422-gwfo1jmu1tm8lcf0
parent: v.ladeuil+lp at free.fr-20080715143602-2jp2woe0opz6r272
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-07-15 15:53:00 +0100
message:
  (awilkins) Fix #247585 and support IIS
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
  bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3538.1.1
    revision-id:v.ladeuil+lp at free.fr-20080715143602-2jp2woe0opz6r272
    parent: pqm at pqm.ubuntu.com-20080715141422-gwfo1jmu1tm8lcf0
    parent: v.ladeuil+lp at free.fr-20080715131153-878puezdlvn6x3hg
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: trunk
    timestamp: Tue 2008-07-15 16:36:02 +0200
    message:
      (awilkins) Fix #247585 and support IIS
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3537.1.1
    revision-id:v.ladeuil+lp at free.fr-20080715131153-878puezdlvn6x3hg
    parent: pqm at pqm.ubuntu.com-20080714082119-ju6qe5weo8pp7f1c
    parent: adwi2 at 014661-xp-20080715104149-1s0zpx6jepkbruu8
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: 247585-IIS-boundary-2
    timestamp: Tue 2008-07-15 15:11:53 +0200
    message:
      Fix some more PEP8isms and delete useless import
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3535.1.4
    revision-id:adwi2 at 014661-xp-20080715104149-1s0zpx6jepkbruu8
    parent: adwi2 at 014661-xp-20080714210916-7vrggx854g9t8chb
    committer: adwi2 <adwi2 at 014661-XP>
    branch nick: bzr.rfc822-quoted-boundary-lines
    timestamp: Tue 2008-07-15 11:41:49 +0100
    message:
      Changes as suggested by Mr Ladeuil.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3535.1.3
    revision-id:adwi2 at 014661-xp-20080714210916-7vrggx854g9t8chb
    parent: adrian.wilkins at gmail.com-20080711143035-4cqrbgtj3dg7drg8
    committer: adwi2 <adwi2 at 014661-XP>
    branch nick: bzr.rfc822-quoted-boundary-lines
    timestamp: Mon 2008-07-14 22:09:16 +0100
    message:
      Fix ability to use IIS as a dumb HTTP server by unquoting the boundary
      lines it emits should the first check fail.
      
      Fix quoted boundary lines bugs exposed by tests in previous revision.
      IIS uses a fixed value for boundary lines, quoted inside angle brackets.
      
      RFC 2046 prohibits use of angles in boundary lines, but IIS uses them
      Python implements RFC 822 unquoting badly and considers angles to be quotes
      Parameters in HTTP response headers get RFC 822 unquoted
      
      Hence all multi-part responses from IIS run foul of boundary line integrity
      checking.
      
      see
      https://bugs.launchpad.net/bzr/+bug/247585
    modified:
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3535.1.2
    revision-id:adrian.wilkins at gmail.com-20080711143035-4cqrbgtj3dg7drg8
    parent: adrian.wilkins at gmail.com-20080711142946-vipeganlhe6gq4dz
    committer: Adrian Wilkins <adrian.wilkins at gmail.com>
    branch nick: bzr.rfc822-quoted-boundary-lines
    timestamp: Fri 2008-07-11 15:30:35 +0100
    message:
      Fix ability to use IIS as a dumb HTTP server.
      
      Fix quoted boundary lines bugs exposed by tests in previous revision.
      IIS uses a fixed value for boundary lines, quoted inside angle brackets.
      
      RFC 2046 prohibits use of angles in boundary lines, but IIS uses them
      Python implements RFC 822 unquoting badly and considers angles to be quotes
      Parameters in HTTP response headers get RFC 822 unquoted
      
      Hence all multi-part responses from IIS run foul of boundary line integrity
      checking.
      
      see
      https://bugs.launchpad.net/bzr/+bug/247585
    modified:
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
    ------------------------------------------------------------
    revno: 3535.1.1
    revision-id:adrian.wilkins at gmail.com-20080711142946-vipeganlhe6gq4dz
    parent: pqm at pqm.ubuntu.com-20080709135859-wq3r1d1fjcafelgw
    committer: Adrian Wilkins <adrian.wilkins at gmail.com>
    branch nick: bzr.rfc822-quoted-boundary-lines
    timestamp: Fri 2008-07-11 15:29:46 +0100
    message:
      Made the behaviour of the existing multi-range test more like the real thing by 
      RFC 822 unquoting parameters
      
      Added a test class which behaves like IIS 6 and 7 when stating multipart boundaries
    modified:
      bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
=== modified file 'NEWS'
--- a/NEWS	2008-07-14 16:16:48 +0000
+++ b/NEWS	2008-07-15 14:36:02 +0000
@@ -46,6 +46,12 @@
 
   BUG FIXES:
 
+    * Bazaar is now able to be a client to the web server of IIS 6 and 7.
+      The broken implementations of RFC822 in Python and RFC2046 in IIS
+      combined with boundary-line checking in Bazaar previously made this
+      impossible. (NB, IIS 5 does not suffer from this problem).
+      (Adrian Wilkins, #247585)
+
     * ``bzr log --long`` with a ghost in your mainline now handles that
       ghost properly. (John Arbash Meinel, #243536)
 

=== modified file 'bzrlib/tests/test_http_response.py'
--- a/bzrlib/tests/test_http_response.py	2008-05-06 15:02:27 +0000
+++ b/bzrlib/tests/test_http_response.py	2008-07-15 13:11:53 +0000
@@ -225,6 +225,7 @@
         self.assertEquals('', f.read(0))
         self.assertEquals('', f.read(1))
 
+
 class TestRangeFileSizeKnown(tests.TestCase, TestRangeFileMixin):
     """Test a RangeFile for a whole file whose size is known."""
 
@@ -253,6 +254,7 @@
         f._pos = 0 # Force an invalid pos
         self.assertRaises(errors.InvalidRange, f.read, 2)
 
+
 class TestRangeFileMultipleRanges(tests.TestCase, TestRangeFileMixin):
     """Test a RangeFile for multiple ranges.
 
@@ -266,10 +268,16 @@
     fact) in real uses but may lead to hard to track bugs.
     """
 
+    # The following is used to represent the boundary paramter defined
+    # in HTTP response headers and the boundary lines that separate
+    # multipart content.
+
+    boundary = "separation"
+
     def setUp(self):
         super(TestRangeFileMultipleRanges, self).setUp()
 
-        boundary = 'separation'
+        boundary = self.boundary
 
         content = ''
         self.first_range_start = 25
@@ -281,19 +289,22 @@
             content += self._multipart_byterange(part, start, boundary,
                                                  file_size)
         # Final boundary
-        content += self._boundary_line(boundary)
+        content += self._boundary_line()
 
         self._file = response.RangeFile('Multiple_ranges_file',
                                         StringIO(content))
+        self.set_file_boundary()
+
+    def _boundary_line(self):
+        """Helper to build the formatted boundary line."""
+        return '--' + self.boundary + '\r\n'
+
+    def set_file_boundary(self):
         # Ranges are set by decoding the range headers, the RangeFile user is
         # supposed to call the following before using seek or read since it
         # requires knowing the *response* headers (in that case the boundary
         # which is part of the Content-Type header).
-        self._file.set_boundary(boundary)
-
-    def _boundary_line(self, boundary):
-        """Helper to build the formatted boundary line."""
-        return '--' + boundary + '\r\n'
+        self._file.set_boundary(self.boundary)
 
     def _multipart_byterange(self, data, offset, boundary, file_size='*'):
         """Encode a part of a file as a multipart/byterange MIME type.
@@ -311,7 +322,7 @@
         :return: a string containing the data encoded as it will appear in the
             HTTP response body.
         """
-        bline = self._boundary_line(boundary)
+        bline = self._boundary_line()
         # Each range begins with a boundary line
         range = bline
         # A range is described by a set of headers, but only 'Content-Range' is
@@ -395,6 +406,31 @@
         self.assertRaises(errors.InvalidHttpResponse, f.read, 1)
 
 
+class TestRangeFileMultipleRangesQuotedBoundaries(TestRangeFileMultipleRanges):
+    """Perform the same tests as TestRangeFileMultipleRanges, but uses 
+    an angle-bracket quoted boundary string like IIS 6.0 and 7.0
+    (but not IIS 5, which breaks the RFC in a different way
+    by using square brackets, not angle brackets)
+    
+    This reveals a bug caused by 
+    
+    - The bad implementation of RFC 822 unquoting in Python (angles are not 
+      quotes), coupled with 
+
+    - The bad implementation of RFC 2046 in IIS (angles are not permitted chars
+      in boundary lines).
+ 
+    """
+    # The boundary as it appears in boundary lines
+    # IIS 6 and 7 use this value
+    _boundary_trimmed = "q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl"
+    boundary = '<' + _boundary_trimmed + '>'
+
+    def set_file_boundary(self):
+        # Emulate broken rfc822.unquote() here by removing angles
+        self._file.set_boundary(self._boundary_trimmed)
+
+
 class TestRangeFileVarious(tests.TestCase):
     """Tests RangeFile aspects not covered elsewhere."""
 

=== modified file 'bzrlib/transport/http/response.py'
--- a/bzrlib/transport/http/response.py	2008-05-22 07:03:44 +0000
+++ b/bzrlib/transport/http/response.py	2008-07-15 13:11:53 +0000
@@ -24,6 +24,7 @@
 
 import httplib
 from cStringIO import StringIO
+import rfc822
 
 from bzrlib import (
     errors,
@@ -107,11 +108,21 @@
             # string entity.
             # To be on the safe side we allow it before any boundary line
             boundary_line = self._file.readline()
+
         if boundary_line != '--' + self._boundary + '\r\n':
-            raise errors.InvalidHttpResponse(
-                self._path,
-                "Expected a boundary (%s) line, got '%s'" % (self._boundary,
-                                                             boundary_line))
+            # rfc822.unquote() incorrectly unquotes strings enclosed in <>
+            # IIS 6 and 7 incorrectly wrap boundary strings in <>
+            # together they make a beautiful bug, which we will be gracious
+            # about here
+            if (self._unquote_boundary(boundary_line) != 
+                '--' + self._boundary + '\r\n'):
+                raise errors.InvalidHttpResponse(
+                    self._path,
+                    "Expected a boundary (%s) line, got '%s'"
+                    % (self._boundary, boundary_line))
+
+    def _unquote_boundary(self, b):
+        return b[:2] + rfc822.unquote(b[2:-2]) + b[-2:]
 
     def read_range_definition(self):
         """Read a new range definition in a multi parts message.




More information about the bazaar-commits mailing list